UDP(User Datagram Protocol),用户数据包协议。
在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的QQ就是使用的UDP协议。
服务器端程序:
#include <WinSock2.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
//加载套接字库,1.1版本
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return 0;
}
//创建套接字
SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
//将套接字绑定到一个本地地址和端口上
SOCKADDR_IN AddrSrv;
AddrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
AddrSrv.sin_family = AF_INET;
AddrSrv.sin_port = htons(6000);
bind(sockSrv,(SOCKADDR *)&AddrSrv,sizeof(AddrSrv));
//接收和发送
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
SOCKADDR_IN AddrClient;//存储发送端的地址信息
int len = sizeof(AddrClient);
while(1)
{
recvfrom(sockSrv,recvBuf,strlen(recvBuf),0,(SOCKADDR*)&AddrClient,&len);
if ('q' == recvBuf[0])
{
sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&AddrClient,len);
cout << "end chat";
break;
}
sprintf_s(tempBuf,"%s say : %s\n",inet_ntoa(AddrClient.sin_addr),recvBuf);
cout << tempBuf;
cout << "你要发送的数据:";
gets(sendBuf);
sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&AddrClient,len);
}
closesocket(sockSrv);
WSACleanup();
}
客户端程序:
#include <WinSock2.h>
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
//加载套接字库,1.1版本
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return 0;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return 0;
}
//创建套接字
SOCKET sockClient = socket(AF_INET,SOCK_DGRAM,0);
//存放要发送到的机器的地址信息
SOCKADDR_IN addr;
addr.sin_addr.S_un.S_addr = inet_addr("59.73.163.254");//要发送的机器的IP
addr.sin_family = AF_INET;
addr.sin_port = htons(6000);//要发送到的机器的端口
//接收和发送
char recvBuf[100];
char sendBuf[100];
char tempBuf[200];
int len = sizeof(SOCKADDR);
while(1)
{
cout << "输入要发送的数据:";
gets(sendBuf);
sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addr,sizeof(addr));
//用addr接收返回的地址结构
recvfrom(sockClient,recvBuf,strlen(recvBuf),0,(SOCKADDR*)&addr,&len);
if ('q' == recvBuf[0])
{
sendto(sockClient,"q",strlen("q")+1,0,(SOCKADDR*)&addr,len);
cout << "end chat";
break;
}
sprintf_s(tempBuf,"%s say :%s\n",inet_ntoa(addr.sin_addr),recvBuf);
cout << tempBuf;
}
closesocket(sockClient);
WSACleanup();
}
UDP编程流程:
另附,一个结构体的说明,和网络字节序的转换。和怎么将一个字符串转成一个点分十进制的IP形式等
note:别忘记附加ws2_32.lib库。然后再建立套接字和绑定时,可以写if语句判断一下,创建套接字、绑定是否成功等。WSAGetLastError()函数可以输出错误码。可以到VS--工具--错误查找中,输入该错误码查找错误!