基于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 <winsock2.h>
#include <stdio.h>
#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 <winsock2.h>
#include <stdio.h>
#include <windows.h>
#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);
}
}