基于UDP的C/S模型代码实现

udp服务器传输层主要应用的协议模型有两种,一种是tcp协议,另外一种则是udp协议。tcp协议在网络通信中占主导地位,绝大多数的网络通信借助tcp协议完成数据传输。但udp也是网络通信中不可或缺的重要通信手段。
相较于tcp而言,udp通信的形式更像是发短信。不需要在数据传输之前建立、维护连接。只专心获取数据就好。省去了三次握手的过程,通信速度可以大大提高,但与之伴随的通信的稳定性和正确率便得不到保证。因此,我们称udp为“无连接的不可靠报文传递”。
那么与我们熟知的tcp相比,udp有哪些优点和不足呢?由于无需创建连接,所以udp开销较小,数据传输速度快,实时性较强。多用于对实时性要求较高的通信场合,如视频会议、电话会议等。但随之也伴随着数据传输不可靠,传输数据的正确率、传输顺序和流量都得不到控制和保证。所以,通常情况下,使用udp协议进行数据传输,为保证数据的正确性,我们需要在应用层添加辅助校验协议来弥补udp的不足,以达到数据可靠传输的目的。
与tcp类似的,udp也有可能出现缓冲区被填满后,再接收数据时丢包的现象。由于它没有tcp滑动窗口的机制,通常采用如下两种方法解决:
1)服务器应用层设计流量控制,控制发送数据速度。
2)借助setsockopt函数改变接收缓冲区大小。如:
#include int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen); int n = 220x1024 setsockopt(sockfd, sol_socket, so_rcvbuf, &n, sizeof(n));c/s模型
由于udp不需要维护连接,程序逻辑简单了很多,但是udp协议是不可靠的,保证通讯可靠性的机制需要在应用层实现。
编译运行server,在两个终端里各开一个client与server交互,看看server是否具有并发服务的能力。用ctrl+c关闭server,然后再运行server,看此时client还能否和server联系上。和tcp程序的运行结果相比较,体会无连接的含义。
server#include #include #include #include #include #include #include #define maxline 80#define serv_port 6666int main(void){ struct sockaddr_in servaddr, cliaddr; socklen_t cliaddr_len; int sockfd; char buf[maxline]; char str[inet_addrstrlen]; int i, n; sockfd = socket(af_inet, sock_dgram, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = af_inet; servaddr.sin_addr.s_addr = htonl(inaddr_any); servaddr.sin_port = htons(serv_port); bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); printf(accepting connections ...n); while (1) { cliaddr_len = sizeof(cliaddr); n = recvfrom(sockfd, buf, maxline,0, (struct sockaddr *)&cliaddr, &cliaddr_len); if (n == -1) perror(recvfrom error); printf(received from %s at port %dn, inet_ntop(af_inet, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port)); for (i = 0; i 编号 命令:ip ad */ group.imr_ifindex = if_nametoindex(eth0); setsockopt(sockfd, ipproto_ip, ip_multicast_if, &group, sizeof(group)); /*构造 client 地址 ip+端口 */ bzero(&clientaddr, sizeof(clientaddr)); clientaddr.sin_family = af_inet; /* ipv4 */ inet_pton(af_inet, group, &clientaddr.sin_addr.s_addr); clientaddr.sin_port = htons(client_port); while (1) { //fgets(buf, sizeof(buf), stdin); sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr)); sleep(1); } close(sockfd); return 0;}client#include #include #include #include #include #include #include #include #include #include #include #define server_port 6666#define maxline 4096#define client_port 9000#define group 239.0.0.2int main(int argc, char *argv[]){ struct sockaddr_in serveraddr, localaddr; int confd; ssize_t len; char buf[maxline]; /* 定义组播结构体 */ struct ip_mreqn group; confd = socket(af_inet, sock_dgram, 0); //初始化本地端地址 bzero(&localaddr, sizeof(localaddr)); localaddr.sin_family = af_inet; inet_pton(af_inet, 0.0.0.0 , &localaddr.sin_addr.s_addr); localaddr.sin_port = htons(client_port); bind(confd, (struct sockaddr *)&localaddr, sizeof(localaddr)); /*设置组地址*/ inet_pton(af_inet, group, &group.imr_multiaddr); /*本地任意ip*/ inet_pton(af_inet, 0.0.0.0, &group.imr_address); /* eth0 -- > 编号 命令:ip ad */ group.imr_ifindex = if_nametoindex(eth0); /*设置client 加入多播组 */ setsockopt(confd, ipproto_ip, ip_add_membership, &group, sizeof(group)); while (1) { len = recvfrom(confd, buf, sizeof(buf), 0, null, 0); write(stdout_fileno, buf, len); } close(confd); return 0;}

荣耀9、荣耀V9对比评测:大小屏王者对决!价格、配置相近的华为荣耀9、华为荣耀V9哪个更好?有什么区别?
方案 | 基于安森美PFC图腾柱控制器NCP1681搭配GaN NCP58921的500W方案
关于FPC连接器下接与软排线接触面的方式
华为mate10引领后置指纹时代,华为mate10又是国内第一个使用安卓8.0
“华大芯人才”卓越工程师讲堂开讲汽车电子芯片规划与展望
基于UDP的C/S模型代码实现
华为p10最新消息:华为P10再曝致命硬件问题,博主:建议售后换机!
Nike发布智能篮球鞋,带有无线充电功能
谷歌与欧盟就人工智能法规对话“富有成效”
电子战接收机种类介绍
微雪电子树莓派游戏机配件包|GamePi20配件包 4.3寸屏介绍
三星Note7虹膜识别很好 就是有一点不好
奥迪城市智能辅助系统功能解析
微型空气质量监测仪【恒美仪器HM-AQI】解决方案
如何在FPGA上使用resizer IP来调整图像的大小
高压柜中电压互感器烧毁的原因分析
AI是如何做到审判公平性的?法官仍然是那个最终做决定的人
中国移动全面升级飞信 拟借5G通道与微信拉回差距
延续摩尔定律的途径除了制程微缩还有先进封装
Volocopter GmbH宣布启动新加坡空中出租车业务