一个简单的QQ聊天代码
来源:互联网 发布:javascript 打印堆栈 编辑:程序博客网 时间:2024/05/01 18:38
#include <winsock2.h>
#include <windows.h>
#include <iostream.h>
#pragma comment (lib,"ws2_32")
#define locport 8000
#define gatport 11282
#define maxsize 40*1024
struct sockaddr_in sin[2][4]={{0}};
SOCKET sock[2][2]={{0}},slisten=INVALID_SOCKET;
BOOL local;
int addrlen=sizeof(struct sockaddr_in);
void start()
{
cout<<" ---------------------------------------------------/n";
cout<<" || || /n";
cout<<" || QQtcp (TCP转发) || /n";
cout<<" || || /n";
cout<<" ---------------------------------------------------"<<endl;
}
void usage()
{
cout<<"/nUsage:/r/n/tQQtcp -l[-g] ip port"<<endl;
cout<<"/tQQtcp -h"<<endl;
cout<<"Example:/r/n";
cout<<"/tQQtcp -l 127.0.0.1 11282"<<endl;
cout<<"/tQQtcp -l 192.168.0.1 11282"<<endl;
cout<<"/tQQtcp -g 61.144.238.156 8000"<<endl;
cout<<"Attention:"<<endl;
cout<<"/t选项 -l : 运行于本机上,ip填网关地址,port必须为11282(网关监听端口);"<<endl;
cout<<"/t QQ客户端所填服务器地址为127.0.0.1,端口为8000(本地监听端口);"<<endl;
cout<<"/t选项 -g : 运行于网关上,ip填腾讯服务器地址,port为腾讯服务器端口;"<<endl;
cout<<"/t选项 -h : 查阅扩展功能及相关帮助文件。"<<endl;
}
DWORD WINAPI t2u(LPVOID param)
{
UNREFERENCED_PARAMETER(param);
fd_set fdread,fdwrite;
int ret,ileft,idx,istbcs=0,iret;
char msgrecv[maxsize]={0},msgsend[maxsize]={0};
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[1][0],&fdread);
FD_SET(sock[1][1],&fdwrite);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
cout<<"/nThread 1 select error: "<<GetLastError()<<endl;
break;
}
if(ret>0)
{
if(FD_ISSET(sock[1][0],&fdread))
{
iret=recv(sock[1][0],msgrecv,sizeof(msgrecv),0);
if(iret==SOCKET_ERROR)
{
cout<<"Thread 1 recv error: "<<GetLastError()<<endl;
break;
}
else if(iret==0)
{
break;
}
cout<<"/nThread 1 TCP Recv "<<iret<<" bytes from "<<inet_ntoa(sin[1][0].sin_addr)<<endl;
memcpy(msgsend+istbcs,msgrecv,iret);
istbcs+=iret;
memset(msgrecv,0,sizeof(msgrecv));
}
else if(FD_ISSET(sock[1][1],&fdwrite))
{
ileft=istbcs;
idx=0;
while(ileft>0)
{
if(sin[1][3].sin_port==htons(0))
{
cout<<"sin[1][3].sin_port==0"<<endl;
break;
}
iret=sendto(sock[1][1],&msgsend[idx],ileft,0,(struct sockaddr *)&sin[1][3],addrlen);
if(iret==SOCKET_ERROR)
{
cout<<"Thread 1 sendto error: "<<GetLastError()<<endl;
break;
}
else if(iret==0)
{
break;
}
cout<<"Thread 1 UDP Send "<<iret<<" bytes to "<<inet_ntoa(sin[1][3].sin_addr)<<endl;
ileft-=iret;
idx+=iret;
}
memset(msgsend,0,sizeof(msgsend));
istbcs=0;
}
}
Sleep(50);
}
return 0;
}
DWORD WINAPI u2t(LPVOID param)
{
UNREFERENCED_PARAMETER(param);
fd_set fdread,fdwrite;
struct sockaddr_in tempr;
int ret,iret,idx,ileft,istbcs=0;
char msgrecv[maxsize]={0},msgsend[maxsize]={0};
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[0][0],&fdread);
FD_SET(sock[0][1],&fdwrite);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
cout<<"/nThread 0 select error: "<<GetLastError()<<endl;
break;
}
if(ret>0)
{
if(FD_ISSET(sock[0][0],&fdread))
{
iret=recvfrom(sock[0][0],msgrecv,sizeof(msgrecv),0,(struct sockaddr *)&tempr,&addrlen);
if(iret==SOCKET_ERROR)
{
cout<<"Thread 0 recvfrom error: "<<GetLastError()<<endl;
break;
}
else if(iret==0)
{
break;
}
if(sin[0][0].sin_port==htons(0))
{
sin[0][0].sin_port=tempr.sin_port;
sin[1][3].sin_port=tempr.sin_port;
}
else if(sin[0][0].sin_port!=tempr.sin_port)
break;
cout<<"/nThread 0 UDP recv "<<iret<<" bytes from "<<inet_ntoa(sin[0][0].sin_addr)<<endl;
memcpy(msgsend+istbcs,msgrecv,iret);
istbcs+=iret;
memset(msgrecv,0,sizeof(msgrecv));
}
else if(FD_ISSET(sock[0][1],&fdwrite))
{
ileft=istbcs;
idx=0;
while(ileft>0)
{
iret=send(sock[0][1],&msgsend[idx],ileft,0);
if(iret==SOCKET_ERROR)
{
cout<<"Thread 0 send error: "<<GetLastError()<<endl;
break;
}
else if(iret==0)
{
break;
}
cout<<"Thread 0 TCP send "<<iret<<" bytes to "<<inet_ntoa(sin[0][3].sin_addr)<<endl;
ileft-=iret;
idx+=iret;
}
memset(msgsend,0,sizeof(msgsend));
istbcs=0;
}
}
Sleep(50);
}
return 0;
}
int main(int argc,char *argv[])
{
WSADATA wsa;
int ret,log;
HANDLE threads[2];
DWORD threadid[2];
system("cls.exe");
start();
if(WSAStartup(MAKEWORD(2,2),&wsa)!=0)
{
cout<<"WSAStartup error: "<<GetLastError()<<endl;
return -1;
}
if(argc==2 && !strcmp(argv[1],"-h"))
{
ShellExecute(NULL,"open","help.txt",NULL,NULL,SW_SHOWMAXIMIZED);
return 0;
}
else if(argc!=4)
{
usage();
return -1;
}
else if(!strcmp(argv[1],"-l"))
{
local=true;
}
else if(!strcmp(argv[1],"-g"))
local=false;
else
{
usage();
return -1;
}
if(local)
{
sin[0][0].sin_addr.s_addr=inet_addr("127.0.0.1");
sin[0][0].sin_family=AF_INET;
sin[0][0].sin_port=htons(0);
sin[0][1].sin_addr.s_addr=htonl(INADDR_ANY);
sin[0][1].sin_family=AF_INET;
sin[0][1].sin_port=htons(locport);
sin[0][2].sin_addr.s_addr=htonl(INADDR_ANY);
sin[0][2].sin_family=AF_INET;
sin[0][2].sin_port=htons(locport);
sin[0][3].sin_addr.s_addr=inet_addr(argv[2]);
sin[0][3].sin_family=AF_INET;
sin[0][3].sin_port=htons(atoi(argv[3]));
}
else
{
sin[0][3].sin_addr.s_addr=htonl(0);
sin[0][3].sin_family=AF_INET;
sin[0][3].sin_port=htons(0);
sin[0][2].sin_addr.s_addr=htonl(INADDR_ANY);
sin[0][2].sin_family=AF_INET;
sin[0][2].sin_port=htons(gatport);
sin[0][1].sin_addr.s_addr=htonl(INADDR_ANY);
sin[0][1].sin_family=AF_INET;
sin[0][1].sin_port=htons(gatport);
sin[0][0].sin_addr.s_addr=inet_addr(argv[2]);
sin[0][0].sin_family=AF_INET;
sin[0][0].sin_port=htons(atoi(argv[3]));
}
for(int i=0;i<4;i++)
sin[1][i]=sin[0][3-i];
if((sock[0][0]=socket(AF_INET,SOCK_DGRAM,0))==INVALID_SOCKET)
{
cout<<"Socket sock[0][0] error: "<<GetLastError()<<endl;
return -1;
}
if(bind(sock[0][0],(struct sockaddr *)&sin[0][1],addrlen)==SOCKET_ERROR)
{
cout<<"Bind sock[0][0] error: "<<GetLastError()<<endl;
return -1;
}
sock[1][1]=sock[0][0];
if(!local)
{
if((slisten=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET)
{
cout<<"Socket slisten error: "<<GetLastError()<<endl;
return -1;
}
if(bind(slisten,(struct sockaddr *)&sin[0][2],addrlen)==SOCKET_ERROR)
{
cout<<"Bind slisten error: "<<GetLastError()<<endl;
return -1;
}
if(listen(slisten,1)==SOCKET_ERROR)
{
cout<<"Listen slisten error: "<<GetLastError()<<endl;
return -1;
}
}
cout<<"正常工作中..."<<endl<<endl;
while(1)
{
if(local)
{
sock[0][1]=socket(AF_INET,SOCK_STREAM,0);
sock[1][0]=sock[0][1];
while(1)
{
if(connect(sock[0][1],(struct sockaddr *)&sin[0][3],addrlen)==SOCKET_ERROR)
{
if(GetLastError()==10061)
cout<<"Remote computer's target port isn't active/r"<<flush;
Sleep(2000);
continue;
}
sin[0][0].sin_port=htons(0);
sin[1][3].sin_port=htons(0);
cout<<"/nConnect Successfully"<<endl;
break;
}
}
else
{
if((sock[1][0]=accept(slisten,(struct sockaddr *)&sin[1][0],&addrlen))==SOCKET_ERROR)
{
cout<<"Accept error: "<<GetLastError()<<endl;
break;
}
sock[0][1]=sock[1][0];
sin[0][3].sin_addr=sin[1][0].sin_addr;
cout<<"Accept Successfully"<<endl;
}
threads[0]=CreateThread(NULL,0,u2t,(LPVOID)0,0,&threadid[0]);
threads[1]=CreateThread(NULL,0,t2u,(LPVOID)1,0,&threadid[1]);
ret=WaitForMultipleObjects(2,threads,false,INFINITE);
if(ret==WAIT_FAILED)
{
cout<<"WaitForMultipleObjects error: "<<GetLastError()<<endl;
return -1;
}
log=ret-WAIT_OBJECT_0;
if(log>=0 && log<2)
{
for(int j=0;j<2;j++)
{
if(threads[i]!=NULL)
CloseHandle(threads[j]);
for(int k=0;k<2;k++)
{
if(sock[j][k]!=INVALID_SOCKET && j!=k)
{
if(sock[j][k]!=INVALID_SOCKET)
closesocket(sock[j][k]);
}
}
}
}
else
break;
}
if(slisten!=INVALID_SOCKET)
closesocket(slisten);
WSACleanup();
return 0;
}
- 一个简单的QQ聊天代码
- 一个简单的聊天代码
- 简单的QQ临时在线聊天功能
- 一个类似QQ的java聊天程序
- 简单版QQ聊天
- QQ强制聊天代码
- QQ在线聊天代码
- QQ双人聊天代码
- qq在线聊天代码
- 一个简单的聊天程序
- QQ加好友代码 强行聊天的代码 HTML
- MSN QQ网页聊天代码
- MSN QQ在线聊天代码
- java 仿QQ聊天代码
- QQ聊天 代码 输入表情
- linux 下简单的模拟QQ 聊天过程 UDP 通讯
- 简单的仿QQ聊天(自娱自乐聊天室)
- 通过Socket实现类似QQ的简单聊天功能
- 函数:递归分类
- sql加密
- 关于visual studio 2005sp1安装问题
- 一个让QQ不能启动的脚本病毒
- 母版页的加载顺序
- 一个简单的QQ聊天代码
- 写了个使用QuickSilver发表饭否消息的脚本..
- 树节点的拖动
- 随便写写今天一些知识点.
- 一周年纪念日
- 最怕做决定
- 不可再犯
- 记毕业
- 随便写写今天一些知识点(二).