基於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
#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);
}
}