socket编程(十四)

来源:互联网 发布:招商总监 知乎 编辑:程序博客网 时间:2024/05/16 17:57

1.UDP特点

(1)无连接

(2)基于消息的数据传输服务

(3)不可靠

(4)一般情况下UDP更加高效

2.UDP客户/服务基本模型

3.UDP回射客户/服务器

server.cpp

#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#define ERR_EXIT(m) \    do \    { \    perror(m); \    exit(EXIT_FAILURE); \    }while(0)void echo_srv(int sock) {char recvbuf[1024] = {0};struct sockaddr_in peeraddr;socklen_t peerlen;int n;while(1) {peerlen = sizeof(peeraddr);memset(recvbuf, 0, sizeof(recvbuf));n = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr*)&peeraddr, &peerlen);if(-1 == n) {if(errno == EINTR)continue;ERR_EXIT("recvfrom");} else {fputs(recvbuf, stdout);sendto(sock, recvbuf, n, 0, (struct sockaddr*)&peeraddr, peerlen); }}close(sock);}int main() {int sock;if((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)ERR_EXIT("socket");struct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(5188);servaddr.sin_addr.s_addr = htonl(INADDR_ANY);if((bind(sock, (struct sockaddr*)&servaddr, sizeof(servaddr))) < 0)ERR_EXIT("bind");echo_srv(sock);return 0;}

client.cpp

#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <errno.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;memset(&servaddr, 0, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(5188);servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr));int ret;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));ret = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, NULL, NULL);if(-1 == ret) {if(errno == EINTR)continue;ERR_EXIT("recvfrom");}fputs(recvbuf, stdout);memset(sendbuf, 0, sizeof(sendbuf));memset(recvbuf, 0, sizeof(recvbuf));}close(sock);}int main() {int sock;if((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0)ERR_EXIT("socket");echo_cli(sock);return 0;}

4.UDP注意点

(1)UDP保温可能丢失,重复

(2)UDP报文可能乱序

(3)UDP缺乏流量控制

(4)UDP协议数据报文截断

(5)recvfrom返回0,不代表连接关闭,因为udp是无连接的

(6)ICMP异步错误:上面代码server.cpp服务器端不启动,./cli执行客户端,不能通知未连接套接字,解决方法:connect

(7)UDP connect

(8)UDP外出接口的确定




原创粉丝点击