一.服务器端Server
1.基本思路:
①加载库:选择一个种类 WSAStartup();
②创建套接字:与外界通信的接口 socket();
③绑定:自己的地址信息 bind();
④收发数据
⑤关闭套接字:closesocket();
⑥卸载库:WSACleanup();
2.代码实现:
1 #include<iostream> 2 #include<Winsock2.h> 3 using namespace std; 4 5 // Need to link with Ws2_32.lib 6 #pragma comment(lib, "ws2_32.lib") 7 8 9 int main() 10 { 11 //1.加载库 12 WORD wVersionRequested; 13 WSADATA wsaData; 14 int err; 15 16 /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ 17 wVersionRequested = MAKEWORD(2, 2); 18 19 err = WSAStartup(wVersionRequested, &wsaData); 20 if (err != 0) { 21 /* Tell the user that we could not find a usable */ 22 /* Winsock DLL. */ 23 printf("WSAStartup failed with error: %d ", err); 24 return 1; 25 } 26 27 /* Confirm that the WinSock DLL supports 2.2.*/ 28 /* Note that if the DLL supports versions greater */ 29 /* than 2.2 in addition to 2.2, it will still return */ 30 /* 2.2 in wVersion since that is the version we */ 31 /* requested. */ 32 33 if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { 34 /* Tell the user that we could not find a usable */ 35 /* WinSock DLL. */ 36 printf("Could not find a usable version of Winsock.dll "); 37 WSACleanup(); 38 return 1; 39 } 40 else 41 printf("The Winsock 2.2 dll was found okay "); 42 43 //2.创建套接字 与外界通信的接口 44 SOCKET sockListen = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 45 if(sockListen == INVALID_SOCKET) 46 { 47 WSACleanup(); 48 return 1; 49 } 50 51 //3.绑定 52 sockaddr_in addr; 53 addr.sin_family = AF_INET; 54 addr.sin_port = htons(1234); 55 //addr.sin_addr.S_un.S_addr = INADDR_ANY; //或是 inet_addr("自己的IP地址") 56 addr.sin_addr.S_un.S_addr = inet_addr("192.168.2.167"); 57 if(SOCKET_ERROR == bind(sockListen,(const sockaddr *)&addr,sizeof(addr))) 58 { 59 closesocket(sockListen); 60 WSACleanup(); 61 return 1; 62 } 63 64 //4.收发数据 65 sockaddr_in addrClient; 66 int nSize = sizeof(addrClient); 67 char szbuf[1024] = {0}; 68 while(1) 69 { 70 int nres = recvfrom(sockListen,szbuf,sizeof(szbuf),0,(sockaddr *)&addrClient,&nSize); 71 72 if(nres > 0) 73 { 74 cout << inet_ntoa(addrClient.sin_addr) << " say: " << szbuf << endl; 75 /*cin >> szbuf; 76 sendto(sockListen,szbuf,sizeof(szbuf),0,(const sockaddr *)&addrClient,sizeof(addrClient));*/ 77 } 78 } 79 80 //关闭套接字 卸载库 81 closesocket(sockListen); 82 WSACleanup(); 83 84 system("pause"); 85 return 0; 86 }
二.客户端Client
1.基本思路:
①加载库:WSAStartup();
②创建套接字:socket();
③绑定:bind();
④收发数据
⑤关闭套接字:closesocket();
⑥卸载库:WSACleanup();
2.代码实现:
1 #include<iostream> 2 #include<Winsock2.h> 3 using namespace std; 4 5 // Need to link with Ws2_32.lib 6 #pragma comment(lib, "ws2_32.lib") 7 8 int main() 9 { 10 //1.加载库 11 WORD wVersionRequested; 12 WSADATA wsaData; 13 int err; 14 15 /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ 16 wVersionRequested = MAKEWORD(2, 2); 17 18 err = WSAStartup(wVersionRequested, &wsaData); 19 if (err != 0) { 20 /* Tell the user that we could not find a usable */ 21 /* Winsock DLL. */ 22 printf("WSAStartup failed with error: %d ", err); 23 return 1; 24 } 25 26 /* Confirm that the WinSock DLL supports 2.2.*/ 27 /* Note that if the DLL supports versions greater */ 28 /* than 2.2 in addition to 2.2, it will still return */ 29 /* 2.2 in wVersion since that is the version we */ 30 /* requested. */ 31 32 if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) { 33 /* Tell the user that we could not find a usable */ 34 /* WinSock DLL. */ 35 printf("Could not find a usable version of Winsock.dll "); 36 WSACleanup(); 37 return 1; 38 } 39 else 40 printf("The Winsock 2.2 dll was found okay "); 41 42 //2.创建套接字 与外界通信的接口 43 SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 44 if(sockClient == INVALID_SOCKET) 45 { 46 WSACleanup(); 47 return 1; 48 } 49 50 //3.绑定 51 sockaddr_in addr; 52 addr.sin_family = AF_INET; 53 addr.sin_port = htons(1234); 54 addr.sin_addr.S_un.S_addr = inet_addr("192.168.2.255"); 55 56 57 //4.收发数据 58 char szbuf[1024] = {0}; 59 while(1) 60 { 61 cin >> szbuf; 62 sendto(sockClient,szbuf,sizeof(szbuf),0,(const sockaddr *)&addr,sizeof(addr)); 63 /*int nres = recvfrom(sockClient,szbuf,sizeof(szbuf),0,0,0); 64 if(nres > 0) 65 { 66 cout << szbuf << endl; 67 }*/ 68 } 69 70 //关闭套接字 卸载库 71 closesocket(sockClient); 72 WSACleanup(); 73 74 system("pause"); 75 return 0; 76 }
注:单线程只能实现一发一收 可以用多线程来解决这个问题
三.UDP特点
①面向无连接:谁发都随时接 广播 多播
②以数据报文的方式来传播:大小固定 不可拆分
③优点:传输效率高
缺点:会有丢包 乱序的可能