上次说的是基于TCP的协议的Socket编程,TCP协议是基于面向连接的可靠通信协议,它具有重发机制,也即当数据被破坏或者丢失的时候,发送方可以将该数据重发。而在数据传输层当中还有一种协议不具备这种重发机制——UDP协议。UDP协议是基于用户数据报协议,比如说当用户使用UDP协议发送了一条消息时,并不知道该消息是否已经到达接收方,或者这个消息已经在传送的过程中丢失,所以它属于不可靠连接通信的协议。但是在即时通信中,UDP协议在对一些对时间要求较高的网络数据传输方面有着重要的作用。
由此,在基于UDP的Soocket编程中,当程序创建套接字句柄成功以后,便可以直接调用函数进行数据的收发,最后关闭套接字对象。在整个过程中,程序都不用调用任何函数连接服务器或者接受客户端的连接事件的操作。在UDP中进行数据收发的函数是sendto()和recvfrom();
Sendto()的函数原型如下:sendto(
SOCKET s,//套接字句柄
const char FAR * buf,//数据缓冲区
int len,//数据的长度
int flags,//一般设置为0
const struct sockaddr FAR * to,//目标地址结构信息
int tolen//目标地址结构大小
);
Recvfrom()函数原型如下:
recvfrom(
SOCKET s,
char FAR * buf,
int len,
int flags,
struct sockaddr FAR * from,//指向地址结构sockaddr_in的指针,表示数据发送方的地址信息
int FAR * fromlen//上地址结构的大小
);
同样,建立服务器端:
#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[10]={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");
if(::recvfrom(s,buff,10,0,(sockaddr*)&addr2,&n)!=-1)//接受客户端信息
{
printf("%s已经连接上...........\r\n",inet_ntoa(addr2.sin_addr));
::sendto(s,sztext,sizeof(sztext),0,(sockaddr*)&addr2,n);//发送数据到客户端
::closesocket(s);//关闭套接字句柄
::WSACleanup();//释放套接字
if(getchar())//如果有输入则关闭程序
{
return 0;//正常结束程序
}
else
{
::Sleep(100);//应用睡眠0.1秒
}
}
return 0;
}
建立客户端:
#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);//初始化套接字库
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,buff,sizeof(buff),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);//应用睡眠0.1秒
}
}
return 0;
}