基于UDP的Winsock编程与基于TCP的Winsock编程相比,只是缺少了一个步骤而已。对于Server,缺少了接受连接的过程(accept()函数调用);对于Client,缺少了请求连接的过程(connect()函数调用)。
另外与TCP区别的还有,在UDP中,数据收发函数是:sendto(),和recvfrom()函数。
函数原型为:
int sendto(SOCKET s,const char FAR *buf,int len,int flags,const struct sockaddr FAR *to,int tolen);
int recvfrom(SOCKET s,char FAR *buf,int len,int flags,struct sockaddr FAR *to,int FAR *fromlen);
参数flags一般设置为0;
参数to为目标地址结构信息;
参数tolen为目标地址结构大小;
废话少说,上代码!
代码:
Server
/*UDPServer.cpp*/
#include
#include
#include <
windows.h> #pragma comment(lib,"WS2_32.lib") int main(){ //初始化套接字库 WSADATA data;//定义结构体变量 WORD w=MAKEWORD(2,0);//定义套接字版本 ::WSAStartup(w,&data);//初始化套接字库 char sztext[]="欢迎你\r\n"; //创建套接字句柄 SOCKET s; s=::socket(AF_INET,SOCK_DGRAM,0);//创建UDP套接字 //地址结构设置及字节转换 sockaddr_in addr,addr2;//创建套接字地址结构变量 int n=sizeof(addr2);//地址结构变量大小 char buff[11]={0};//接收数据缓冲区 addr.sin_family=AF_INET; addr.sin_port=htons(75); addr.sin_addr.S_un.S_addr=INADDR_ANY; //绑定套接字 ::bind(s,(sockaddr*)&addr,sizeof(addr)); printf("UDP服务器已启动\r\n");//提示 while(true){ //从客户端接受数据 if(::recvfrom(s,buff,10,0,(sockaddr*)&addr2,&n)!=0){ printf("%s已经连接上\r\n",inet_ntoa(addr2.sin_addr)); printf("%s\r\n",buff); //发送数据到客户端 ::sendto(s,sztext,sizeof(sztext),0,(sockaddr*)&addr2,n); break; } } //关闭套接字 ::closesocket(s); //关闭套接字库 ::WSACleanup(); if(getchar()){ return 0; }else{ ::Sleep(100); } }
Client
/*UDPClient.cpp*/
#include
#include
#include
#pragma comment(lib,"WS2_32.lib")//连接套接字库 int main(){ //初始化套接字库 WSADATA data;//参数1 WORD w=MAKEWORD(2,0);//参数2,表示套接字版本为2.0 ::WSAStartup(w,&data); char sztext[]="服务器你好!\r\n"; //创建套接字句柄 SOCKET s; s=::socket(AF_INET,SOCK_DGRAM,0);//创建UDP套接字 //地址结构设置及字节转换 sockaddr_in addr,addr2; int n=sizeof(addr2); char buff[10]={0}; addr.sin_family=AF_INET; addr.sin_port=htons(75); addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); printf("UDP客户端已经启动\r\n"); //给服务器发送信息 if(::sendto(s,sztext,sizeof(sztext),0,(sockaddr*)&addr,n)!=0){ //从服务器接受信息 ::recvfrom(s,buff,10,0,(sockaddr*)&addr2,&n); printf("服务器说:%s\r\n",buff); //关闭套接字 ::closesocket(s); //关闭套接字库 ::WSACleanup(); } if(getchar()){ return 0; }else{ ::Sleep(100); } }