与面向连接的协议相比,面向无连接协议极为不同。其中一个重要的不同点就是客户端与服务器之间不必建立连接。
对于UDP套接字编程而言,服务器创建套接字后,调用bind()函数将套接字与准备接收数据的接口绑定在一起。和TCP编程不同的是,应用程序不必调用listen()和accept()函数等待客户端的连接。而只需要等待接收数据了。开发UDP套接字应用程序,有两个重要的函数sendto()和recvfrom()。服务器采用recvfrom()来接收来自客户端的数据报,并获得客户端的端地址,之后向客户端发送数据时,采用sendto()函数。
以下是一个服务器从客户端接收消息,并回送一个消息的算法过程,实现如下:
#include <stdio.h>
#include <winsock.h>
#define CPORT 1520
#define VERSIONRE MAKEWORD(2, 2)
int main()
{
int s; //define two sockets
int nError;
WSADATA wsadata;
struct sockaddr_in sin, clientaddr; //define an address
int retVal;
char buf[64];
int addrLen;
addrLen = sizeof(clientaddr);
memset(buf,64,0);
nError = WSAStartup(VERSIONRE, &wsadata);
if (nError != 0)
{
printf("None avaliable DLL!\n");
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons((unsigned short)CPORT);
sin.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
s = socket(AF_INET,SOCK_DGRAM,0);//make a socket
if (s == INVALID_SOCKET)
{
printf("socket failed!\n");
closesocket(s);
WSACleanup();
return -1;
}
retVal = bind(s, (struct sockaddr*)(&sin), sizeof(sin));//bind socket to address
if (retVal == SOCKET_ERROR)
{
printf("bind failed!\n");
closesocket(s);
WSACleanup();
return -1;
}
retVal = recvfrom(s, buf, 64, 0, (struct sockaddr*)(&clientaddr),&addrLen);
if (retVal == SOCKET_ERROR)
{
printf("recv failed!\n");
closesocket(s);
WSACleanup();
return -1;
}
buf[retVal] = 0;
printf("%s\n",buf);
memset(buf, 64, 0);
strcpy(buf,"Hello!\n");
retVal = sendto(s, buf, 64, 0, (struct sockaddr*)(&clientaddr),sizeof(clientaddr));
if (retVal == SOCKET_ERROR)
{
printf("send failed!\n");
closesocket(s);
WSACleanup();
return -1;
}
closesocket(s);//close socket
WSACleanup();
return 0;
}
对于客户端来说,创建套接字后不必与服务器建立连接,而是直接向服务器发送数据。
#include <stdio.h>
#include <winsock.h>
#define CPORT 1520
#define VERSIONRE MAKEWORD(2, 2)
int main()
{
int s; //define a socket
int nError;
WSADATA wsadata;
struct sockaddr_in sin; //define an address
int sendval;
char buf[64];
int addrLen;
addrLen = sizeof(sin);
memset(buf, 64, 0);
strcpy(buf, "MyUDP");
nError = WSAStartup(VERSIONRE, &wsadata);
if (nError != 0)
{
printf("wsastartup failed!\n");
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons((unsigned short)CPORT);
sin.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
s = socket(AF_INET,SOCK_DGRAM,0);//make a socket
if (s == INVALID_SOCKET)
{
printf("socket failed!\n");
WSACleanup();
return -1;
}
sendval = sendto(s, buf, strlen(buf), 0, (struct sockaddr *)(&sin), sizeof(sin));
if (sendval == SOCKET_ERROR)
{
printf("send failed!\n");
closesocket(s);
WSACleanup();
return -1;
}
sendval = recvfrom(s, buf, 64, 0, (struct sockaddr*)(&sin),&addrLen);
if (sendval == SOCKET_ERROR)
{
printf("recv failed!\n");
closesocket(s);
WSACleanup();
return -1;
}
printf("%s\n",buf);
closesocket(s);//close socket
WSACleanup();
return 0;
}