首先加入ws2_32.lib静态链接库:项目-属性-配置属性-链接器-输入-附加依赖项
或者在声明处加入#pragma comment(lib,"ws2_32.lib")
服务器端:
1 #include <iostream> 2 #include <winsock2.h>//2.0版本 3 #include <process.h>//_beginthreadex的头文件 4 #include <windows.h>//Sleep的头文件 5 using namespace std; 6 SOCKET serveSocket,clientSocket; 7 struct sockaddr_in addrSrv; 8 struct sockaddr_in addrCli; 9 char ip[20]; 10 int InitSocket()//初始化套接字 11 { 12 13 14 WSADATA wsaData; 15 int err; 16 err = WSAStartup(MAKEWORD(2,2),&wsaData); 17 //该函数执行成功后返回0。 18 if (err != 0) 19 { 20 cout<<"加载套接字库失败"<<endl; 21 return 0; 22 } 23 24 addrSrv.sin_addr.s_addr=htonl(INADDR_ANY);
//计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。
//Internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,
//在Internet上传输数据时就需要进行转换。
//多网卡的主机 //= inet_addr("127.0.0.1");//IP地址 25 addrSrv.sin_family=AF_INET;//协议 26 addrSrv.sin_port=htons(5020如果设置为0则随机选一个端口);//端口, 27 28 29 serveSocket = socket(AF_INET,SOCK_STREAM,0); 30 if (serveSocket == INVALID_SOCKET) 31 { 32 cout<<"创建套接字失败!"<<endl; 33 return 0; 34 } 35 36 err = bind(serveSocket,(sockaddr*)&addrSrv,sizeof(sockaddr)); //绑定端口和IP地址 37 if (err == SOCKET_ERROR) 38 { 39 closesocket(serveSocket); 40 cout<<"绑定失败"<<endl; 41 return 0; 42 } 43 } 44 45 void CleanFun()//清理套接字 46 { 47 closesocket(serveSocket);//执行成功就返回0,否则返回SOCKET_ERROR。 48 closesocket(clientSocket);//成功就返回0,否则返回SOCKET_ERROR。 49 WSACleanup(); 50 } 51 52 UINT __stdcall ListenThread(LPVOID lParam)//监听线程 53 { 54 while(1) 55 { 56 int erro = listen(serveSocket,5);//开启监听成功返回0,失败返回SOCKET_ERROR.最大连接数1-5 57 if (erro == SOCKET_ERROR) 58 { 59 return 1; 60 //执行成功,则返回0;如果执行失败,则返回SOCKET_ERROR。 61 } 62 int len = sizeof(addrCli); 63 clientSocket = accept(serveSocket,(sockaddr*)&addrCli,&len); 64 if (clientSocket == INVALID_SOCKET) 65 { 66 return 1; 67 } 68 char * ipaddr = inet_ntoa(addrCli.sin_addr); 69 memcpy(ip,ipaddr,strlen(ipaddr)); 70 cout<<"客户端 " << ip<<" 连接!"<<endl; 71 Sleep(100); 72 } 73 return 1; 74 } 75 76 //发送线程 77 UINT __stdcall SendThread(LPVOID lParam) 78 { 79 char sendBuf[65535]; 80 ZeroMemory(sendBuf,sizeof(sendBuf)); 81 while(1) 82 { 83 cin.getline(sendBuf,65535); 84 if(send(clientSocket,sendBuf,sizeof(sendBuf),0) == SOCKET_ERROR) 85 { 86 //套接字,缓冲区,缓冲区大小,0 87 //send把s的发送缓冲中的数据传到连接的另一端的, 88 //而是协议传的,send仅仅是把buf中的数据copy到s的发送缓冲区的剩余空间里 89 //如果send函数copy数据成功,就返回实际copy的字节数 90 cout<<"发送失败!"; 91 return 0; 92 } 93 } 94 return 1; 95 } 96 //接收线程 97 UINT __stdcall RecvThread(LPVOID lParam) 98 { 99 while(1) 100 { 101 char szBuffer[65535]; 102 ZeroMemory(szBuffer, sizeof(szBuffer)); 103 int ret; 104 ret = recv(clientSocket,szBuffer,sizeof(szBuffer),0); 105 if(ret == 0) 106 { 107 cout<<"接收套接字失败"<<endl; 108 return 0; 109 } 110 if (ret > 0) 111 { 112 cout << ip <<":" << szBuffer << endl; 113 } 114 Sleep(100); 115 } 116 117 return 1; 118 } 119 120 int main(void) 121 { 122 ZeroMemory(ip,sizeof(ip));//ip初始化置0,API函数,相当于memset(ip,'\0',sizeof(ip)); 123 InitSocket(); 124 cout<<"服务器已启动:"<<endl; 125 _beginthreadex(NULL,NULL,ListenThread,NULL,NULL,NULL); 126 _beginthreadex(NULL,NULL,RecvThread,NULL,NULL,NULL); 127 _beginthreadex(NULL,NULL,SendThread,NULL,NULL,NULL); 128 129 while(1) 130 { 131 Sleep(100);//主界面循环,让线程有时间运行,并且Sleep,空循环会卡死 132 } 133 CleanFun(); 134 return 1; 135 136 }
客户端:
1 #include<iostream> 2 #include<WinSock2.h> 3 #include <process.h> 4 #include <string> 5 #include <windows.h> 6 using namespace std; 7 SOCKET clientSocket; 8 sockaddr_in addrClient; 9 int InitSocket() 10 { 11 WSADATA wsaData; 12 int err; 13 err = WSAStartup(MAKEWORD(2,2),&wsaData); 14 if (err != 0) 15 { 16 cout<<"加载套接字库失败"<<endl; 17 return 0; 18 } 19 20 addrClient.sin_addr.s_addr = inet_addr("192.168.59.69");//=htonl(INADDR_ANY);// 21 addrClient.sin_family=AF_INET; 22 addrClient.sin_port=htons(5020); 23 24 25 clientSocket = socket(AF_INET,SOCK_STREAM,0); 26 if (clientSocket == INVALID_SOCKET) 27 { 28 cout<<"创建套接字失败!"<<endl; 29 return 0; 30 } 31 //客户端不需要绑定 32 if(connect(clientSocket,(sockaddr*)&addrClient,sizeof(addrClient)) == SOCKET_ERROR) 33 { 34 cout<<"连接服务器失败!"; 35 //如果连接成功,connect返回0;如果失败则返回SOCKET_ERROR 36 return 1; 37 } 38 return 1; 39 40 } 41 void CleanFun() 42 { 43 closesocket(clientSocket);//成功就返回0,否则返回SOCKET_ERROR。 44 WSACleanup();//解除与Socket库的绑定并且释放Socket库所占用的系统资源 45 } 46 47 //发送线程 48 UINT __stdcall SendThread(LPVOID lParam) 49 { 50 char sendBuf[65535]; 51 ZeroMemory(sendBuf,sizeof(sendBuf)); 52 while(1) 53 { 54 cin.getline(sendBuf,65535); 55 if(send(clientSocket,sendBuf,sizeof(sendBuf),0) == SOCKET_ERROR) 56 { 57 cout<<"发送失败!"; 58 return 0; 59 } 60 Sleep(50); 61 } 62 return 1; 63 } 64 65 //接收线程 66 UINT __stdcall RecvThread(LPVOID lParam) 67 { 68 while(1) 69 { 70 char szBuffer[65535]; 71 ZeroMemory(szBuffer, sizeof(szBuffer)); 72 int ret; 73 ret = recv(clientSocket,szBuffer,sizeof(szBuffer),0); 74 if(ret == 0) 75 { 76 cout<<"接收套接字失败"<<endl; 77 return 0; 78 } 79 if (ret > 0) 80 { 81 cout <<"服务器:"<< szBuffer << endl; 82 } 83 Sleep(50); 84 } 85 86 return 1; 87 } 88 int main(void) 89 { 90 InitSocket(); 91 _beginthreadex(NULL,NULL,SendThread,NULL,NULL,NULL); 92 _beginthreadex(NULL,NULL,RecvThread,NULL,NULL,NULL); 93 while(1) 94 { 95 Sleep(500); 96 } 97 CleanFun(); 98 }