C++基础--Socket C/S UDP通信
原来,UDP通信,比我想象中简单的多!
// WindowsSocketServer.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <string> #include <Windows.h> #include <Winsock2.h> #include <fstream> #pragma comment(lib,"Ws2_32.lib") using namespace std; #define PORT 8080 #define IP_ADDRESS "172.16.20.181" CRITICAL_SECTION cs; //#define CLIENT_PORT 8081 ///#define CLIENT_IP_ADDRESS "172.16.20.181" //接收每个客户端连接的处理函数 DWORD WINAPI ClientThread(LPVOID lpParameter); //连接和服务器端有连接的客户端 DWORD WINAPI ConnectClientsThread(LPVOID lpParameter); int main(int argc, char* argv[]) { //版本协商 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return 0; } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return 0; } /* The WinSock DLL is acceptable. Proceed. */ //创建数据报套接字 SOCKET svr = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); //创建本地地址信息 SOCKADDR_IN addr; addr.sin_family = AF_INET; addr.sin_port = htons(6000); addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); int len = sizeof(sockaddr); int bindflag = bind(svr,(sockaddr*)&addr,len); if( bindflag ==SOCKET_ERROR ) { printf("服务器绑定失败!\n"); system("pause"); return 0; } else { printf("服务器端绑定完成。\n"); } //创建客户端地址对象 SOCKADDR_IN addrClient; char recvBuf[128]; char sendBuf[128]; char tempBuf[256]; while(true) { //接收数据 recvfrom(svr,recvBuf,128,0,(sockaddr*)&addrClient,&len); char* ipClient = inet_ntoa(addrClient.sin_addr); sprintf(tempBuf,"接收来自客户端 %s 的数据: %s\n",ipClient,recvBuf); printf("%s",tempBuf); gets_s(sendBuf); //发送数据 sendto(svr,sendBuf,strlen(sendBuf)+1,0,(sockaddr*)&addrClient,len); } closesocket(svr); WSACleanup(); return 0; }
// WindowsSocketClient.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <iostream> #include <Winsock2.h> #include <Windows.h> #include <fstream> #include <map> #include <string> #include <sstream> #pragma comment(lib,"Ws2_32.lib") using namespace std; #define PORT 8080 #define IP_ADDRESS "172.16.20.181" #define LISTEN_PORT 8081 #define LISTEN_IP_ADDRESS "172.16.20.181" //发送消息结构体 struct SendMsgStruct { SOCKET clientSocket; string msg; struct sockaddr_in ServerAddr; }; //接收消息结构体 struct RecvMsgStruct { SOCKET clientSocket; struct sockaddr_in ServerAddr; }; //发送消息子线程 DWORD WINAPI SendThread(LPVOID lpParameter); //接收消息子线程 DWORD WINAPI RecvThread(LPVOID lpParameter); //去除字符串首尾空格 void trim(string &str); //监听服务器的连接 DWORD WINAPI ListenServerThread(LPVOID lpParameter); int _tmain(int argc, _TCHAR* argv[]) { //版本协商 WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 1, 1 ); err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ return 0; } /* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */ if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup( ); return 0; } /* The WinSock DLL is acceptable. Proceed. */ //创建服务器套接字 SOCKET Svr = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); //创建地址 SOCKADDR_IN addrSvr; addrSvr.sin_family = AF_INET; addrSvr.sin_port = htons(6000); addrSvr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); char recvBuf[128]; char sendBuf[128]; int len = sizeof(sockaddr); while(true) { printf("输入数据,传输给服务端"); gets(sendBuf); //发送数据 sendto(Svr,sendBuf,strlen(sendBuf)+1,0,(sockaddr*)&addrSvr,len); //接收数据 recvfrom(Svr,recvBuf,128,0,(sockaddr*)&addrSvr,&len); char* ipSvr = inet_ntoa(addrSvr.sin_addr); printf("来自 %s 的消息: %s\n",ipSvr,recvBuf); } closesocket(Svr); WSACleanup(); return 0; } //接收消息子线程 DWORD WINAPI RecvThread(LPVOID lpParameter) { RecvMsgStruct *recvStruct=(RecvMsgStruct *)lpParameter; SOCKET clientSocket = recvStruct->clientSocket; struct sockaddr_in ServerAddr = recvStruct->ServerAddr; char recvBuf[500]={"0"}; int byteRecv = recv(clientSocket, recvBuf, 500, 0); int connectState; while( byteRecv == 0 ) { //连接断开,重连 cout<<"byteRecv == 0"<<endl; shutdown(clientSocket,2); //closesocket(ClientSocket); clientSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); connectState = connect(clientSocket,(struct sockaddr*)&ServerAddr, sizeof(ServerAddr)); if( connectState == SOCKET_ERROR ) { cout<<"建立连接发生错误,错误代码:"<<GetLastError()<<endl; } else { cout<<"-----------------------------------------------In"<<endl; } Sleep(5000); } cout<<recvBuf<<endl; while( true ){} return 0; } //移除字符串首尾空格 void trim(string &str) { str.erase(str.find_last_not_of(' ')+1,string::npos); str.erase(0,str.find_first_not_of(' ')); }