设计模型
服务器和客户端启动没有顺序之分(因为不需要三次握手,这也是与TCP的区别)
客户端启动就直接发数据
服务端启动就直接接数据
UDP基本函数使用简化图
代码如下:
LocalUDPServer.cpp
#include <tchar.h> // _T宏 #include <stdio.h>// printf sprintf #include <iostream>// cout fstream using namespace std; // windows socket #include <winsock.h> #pragma comment (lib,"ws2_32.lib") bool initSocketLib(); void main() { if(!initSocketLib()) return; // 初始化本地客户端套接字 SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(serSocket == INVALID_SOCKET) { printf("socket error !"); return ; } sockaddr_in serAddr; serAddr.sin_family = AF_INET; serAddr.sin_port = htons(514); serAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1")/*INADDR_ANY*/; if(bind(serSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) { printf("bind error !"); closesocket(serSocket); return ; } sockaddr_in remoteAddr; int nAddrLen = sizeof(remoteAddr); while (true) { char recvData[255]; int ret = recvfrom(serSocket, recvData, 255, 0, (sockaddr *)&remoteAddr, &nAddrLen); if (ret > 0) { recvData[ret] = 0x00; printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr)); printf(recvData); } //char * sendData = "一个来自服务端的UDP数据包\n"; //sendto(serSocket, sendData, strlen(sendData), 0, (sockaddr *)&remoteAddr, nAddrLen); } closesocket(serSocket); WSACleanup(); return; } bool initSocketLib() { WSADATA Data; //初始化windows Socket Dll int status = WSAStartup(MAKEWORD(1,1),&Data); if (0!=status) { printf(_T("初始化失败\n")); return false; } return true; }RemoteUDPServer.cpp
#include <tchar.h> // _T宏 #include <stdio.h>// printf sprintf #include <iostream>// cout fstream using namespace std; // windows socket #include <winsock.h> #pragma comment (lib,"ws2_32.lib") bool initSocketLib(); void main() { if(!initSocketLib()) return; // 初始化本地客户端套接字 SOCKET serSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(serSocket == INVALID_SOCKET) { printf("socket error !"); return ; } // "本地"的服务端地址映射(IP:port) sockaddr_in serAddr; serAddr.sin_family = AF_INET; serAddr.sin_port = htons(514); serAddr.sin_addr.S_un.S_addr = inet_addr("192.168.0.53");// 因为这是远程机器,客户端也不在本机上,所以绑定实际的物理地址 if(bind(serSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) { printf("bind error !"); closesocket(serSocket); return ; } sockaddr_in remoteAddr; int nAddrLen = sizeof(remoteAddr); while (true) { char recvData[255]; int ret = recvfrom(serSocket, recvData, 255, 0, (sockaddr *)&remoteAddr, &nAddrLen); if (ret > 0) { recvData[ret] = 0x00; printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr)); printf(recvData); } //char * sendData = "一个来自服务端的UDP数据包\n"; //sendto(serSocket, sendData, strlen(sendData), 0, (sockaddr *)&remoteAddr, nAddrLen); } closesocket(serSocket); WSACleanup(); return ; } bool initSocketLib() { WSADATA Data; //初始化windows Socket Dll int status = WSAStartup(MAKEWORD(1,1),&Data); if (0!=status) { printf(_T("初始化失败\n")); return false; } return true; }LocalUDPClient.cpp
#include <tchar.h> // _T宏 #include <stdio.h>// printf sprintf #include <iostream>// cout fstream using namespace std; // windows socket #include <winsock.h> #pragma comment (lib,"ws2_32.lib") bool initSocketLib(); void main() { if(!initSocketLib()) return; // 初始化本地客户端套接字 SOCKET sclient = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(sclient == INVALID_SOCKET) { printf("socket error !"); return; } // 本地的服务端地址映射(IP:port) sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(514); sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); int len = sizeof(sin); // 远程的服务端地址映射(IP:port) sockaddr_in sinEx; sinEx.sin_family = AF_INET; sinEx.sin_port = htons(514); sinEx.sin_addr.S_un.S_addr = inet_addr("192.168.0.53"); int lenEx = sizeof(sinEx); char sendData[512]; UINT iCount = 0; while (true) { memset(sendData,0,512); sprintf(sendData,"client Send =\n",iCount++); int senRet = sendto(sclient, sendData, strlen(sendData), 0, (sockaddr *)&sin, len); if(senRet == SOCKET_ERROR ){ printf("send is error"); } senRet = sendto(sclient, sendData, strlen(sendData), 0, (sockaddr *)&sinEx, lenEx); if(senRet == SOCKET_ERROR ){ printf("send is error"); } printf(sendData); /* 这段注释的代码可以加上,为了理解UDP编程没必要 char recvData[255]; int ret = recvfrom(sclient, recvData, 255, 0, (sockaddr *)&sin, &len); if(ret > 0) { recvData[ret] = 0x00; printf(recvData); } */ Sleep(1000);// 发的太快也没啥意思 } closesocket(sclient); WSACleanup(); return; } bool initSocketLib() { WSADATA Data; //初始化windows Socket Dll int status = WSAStartup(MAKEWORD(1,1),&Data); if (0!=status) { printf(_T("初始化失败\n")); return false; } return true; }