14.基于UDP协议的socket编程(1)

来源:互联网 发布:欧舒丹护手霜味道知乎 编辑:程序博客网 时间:2024/05/01 09:41

一.UDP 网络通信模型

下面依照通信流程,我们来实现一个UDP回射客户/服务器




服务器程序


#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <string.h>#define ERR_EXIT(m) \do{ \perror(m); \exit(EXIT_FAILURE); \}while(0)void echo_ser(int sock){char recvbuf[1024] = {0};struct sockaddr_in peeraddr;socklen_t peerlen;int n;while(1){peerlen = sizeof(peeraddr);bzero(recvbuf,sizeof(recvbuf));n= recvfrom(sock,recvbuf,sizeof(recvbuf),0,(struct sockaddr*)&peeraddr,&peerlen);if(n == -1){if(errno == EINTR)continue;ERR_EXIT("recvfrom error");}if(n > 0){fputs(recvbuf,stdout); // 打印接收到的数据sendto(sock,recvbuf,n,0,(struct sockaddr*)&peeraddr,peerlen);}}close(sock);}int main(){int sock;if((sock = socket(AF_INET,SOCK_DGRAM,0))<0)ERR_EXIT("socket err");struct sockaddr_in servaddr;bzero(&servaddr,sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(5188);//servaddr.sin_addr.s_addr = htonl(INADDR_ANY);servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");// 服务器需要绑定地址 if(bind(sock,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)ERR_EXIT("bind err");echo_ser(sock);return 0;}


客户端程序


#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <string.h>#define ERR_EXIT(m) \do{ \perror(m); \exit(EXIT_FAILURE); \}while(0)void echo_cli(int sock){struct sockaddr_in servaddr;bzero(&servaddr,sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(5188);servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");char sendbuf[1024]={0};char recvbuf[1024]={0};while(fgets(sendbuf,sizeof(sendbuf),stdin) != NULL) // 输入保存到发送缓冲区中{sendto(sock,sendbuf,strlen(sendbuf),0,(struct sockaddr*)&servaddr,sizeof(servaddr));recvfrom(sock,recvbuf,sizeof(recvbuf),0,NULL,NULL); // 并不关心发送者的IP地址与端口号fputs(recvbuf,stdout);bzero(sendbuf,sizeof(sendbuf));bzero(recvbuf,sizeof(recvbuf));}}int main(){int sock;if((sock = socket(AF_INET,SOCK_DGRAM,0))<0)ERR_EXIT("socket err");echo_cli(sock);return 0;}

由于UDP不需要维护连接,程序逻辑简单了很多,但是UDP协议是不可靠的,实际上有很多保证通讯可靠性的机制需要在应用层实现。编译运行server,在两个终端里各开一个client与server交互,看看server是否具有并发服务的能力。用Ctrl+C关闭server,然后再运行server,看此时client还能否和server联系上。和前面TCP程序的运行结果相比较,体会无连接的含义。



0 0