UDP是无连接不可靠的数据报协议,UDP的常见应用程序是DNS(域名解析系统),NFS(网络文件系统),SNMP(简单网络管理协议);
在使用UDP的客户服务器程序中,客户不与服务器建立连接,而是只管使用sendto函数给服务器发送数据报,其中必须指出目标服务器的地址;同样,服务器不接受来自客户的连接,而只是用recvfrom等待指定用户的数据到达,recvfrom将与所接收的数据报一起返回客户的协议地址,因此服务器可以把响应发送给正确的客户!!!!
注意:在UDP服务中,必须先由客户发送数据给服务器,这样服务器才会知道自己在为哪个客户服务
编写UDP无连接的客户服务器套接字流程如下:
以下是一个UDP实现的客户服务器发送数据报的简单例子:
//服务器端的代码
#include
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 7070
#define SERVER_IP "192.168.3.66"
int main(int ac, char *av[])
{
int sockser = socket(AF_INET, SOCK_DGRAM, 0); //创建服务器端的套接字
if(sockser == -1){
perror("socket");
}
//设置地址重用
int y=1;
setsockopt(sockser, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int));
struct sockaddr_in addrser, addrcli; //客户服务器的地址结构体
addrser.sin_family = AF_INET; //设置服务器端的协议家族
addrser.sin_port = htons(SERVER_PORT); //设置服务器的端口号
addrser.sin_addr.s_addr = inet_addr(SERVER_IP); //设置服务器的IP地址
socklen_t addrlen = sizeof(struct sockaddr); //得到客户服务器的地址长度
int res = bind(sockser, (struct sockaddr*)&addrser, addrlen); //绑定服务器的地址信息
if(res == -1){
perror("bind");
}
char sendbuf[256];
char recvbuf[256];
printf("wait cli connect.......\n");
//收发数据进行服务
while(1){
recvfrom(sockser, recvbuf, 256, 0, (struct sockaddr*)&addrcli, &addrlen); //接收来自目标客户的数据报
printf("cli:>%s\n", recvbuf);
printf("Ser:>");
scanf("%s", sendbuf);
if(strncmp(sendbuf, "quit", 4) == 0){
sendto(sockser, sendbuf, strlen(sendbuf) + 1, 0, (struct sockaddr*)&addrcli, addrlen); //给目标客户发送数据报
break;
}
sendto(sockser, sendbuf, strlen(sendbuf) + 1, 0, (struct sockaddr*)&addrcli, addrlen);
}
close(sockser); //关闭服务器的套接字
return 0;
}
//客户端的代码
#include
#include
#include
#include
#include
#include
#include
#define SERVER_PORT 7070
#define SERVER_IP "192.168.3.66"
int main(int ac, char *av[])
{
int sockcli = socket(AF_INET, SOCK_DGRAM, 0); //得到客户端的套接字
if(sockcli == -1){
perror("socket");
}
struct sockaddr_in addrser; //服务器端的地址结构体
addrser.sin_family = AF_INET; //设置服务器的地址协议家族
addrser.sin_port = htons(SERVER_PORT); //设置服务器的端口号
addrser.sin_addr.s_addr = inet_addr(SERVER_IP); //设置服务器的IP地址
socklen_t addrlen = sizeof(struct sockaddr); //得到服务器的地址长度
char sendbuf[256];
char recvbuf[256];
printf("cli connect ser ok.\n");
//收发数据
while(1){
printf("Cli:>");
scanf("%s", sendbuf);
if(strncmp(sendbuf, "quit", 4) == 0){
sendto(sockcli, sendbuf, strlen(sendbuf) + 1, 0, (struct sockaddr*)&addrser, addrlen); //客户端首先发送数据报,为了让服务器确认通信的客户
break;
}
sendto(sockcli, sendbuf, strlen(sendbuf) + 1, 0, (struct sockaddr*)&addrser, addrlen);
recvfrom(sockcli, recvbuf, 256, 0, (struct sockaddr*)&addrser, &addrlen); //客户端接收来自服务器的数据报
printf("Ser:>%s\n", recvbuf);
}
close(sockcli); //关闭客户端套接字
return 0;
}