1. UDP简介

  UDP 和TCP 的区别包括 1. 面向字节流和面向报文 2. TCP必须要建立连接后才能进行数据交换,但是UDP则并没有连接的建立和释放过程。面向字节流说明,tcp报文段(segment)是没有边界的,当服务器发送多个报文段到客户端时,客户端可能会把着多个报文段合并成一个报文段进行接收。但是对于UDP来说,数据是通过报文段进行传输的。

  如果说TCP协议可以用打电话去比喻,那么UDP协议可以用邮箱来形容。用邮箱传递信息时,虽然有丢失的可能性。但是用户1发送的信件和用户2接受的信件肯定是相同的。

2. 用UDP编写echo server

  使用UDP,我们只需要修改一下socket函数的参数就OK了。

int client_sock = socket(PF_INET, SOCK_DGRAM, );

  然后就是创建两个表示客户端和服务端地址的sockaddr_in结构,其中serv_addr的各个字段需要我们自己填充。但是client_addr的各个字段是通过recvfrom通过指针进行自动填充。

struct sockaddr_in serv_addr, client_addr;

  填充serv_addr的各个字段:

 serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons();

   下来使用bind函数将套接字和服务器地址进行绑定。

 if (bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < ) {
err_exit("bind error");
}

  数据传输方面使用recv族和sendto进行数据传输,这里值得注意的是只有sendto中的sockaddr_in结构是需要手动填充的,sendto中的地址表示要发送的目标地址。recvfrom中的是获取数据的源地址。下图是echo服务器的交互流程。

      

3. 地址长度所遇到的一个坑

   在写echo服务器中遇到一个问题,服务器端在运行过程中总是会出现如下错误:
  在stackoverflow看了下知道了应该是sockaddr的问题。出问题的代码就是下面这一行。问题就在client_addr这块。
int sLen = sendto(serv_sock, buffer, rLen, MSG_CONFIRM,
(struct sockaddr *)&client_addr, recv_addr_len);

  client_addr是通过服务端调用recvfrom获取的,我心想这也不用我手动填啊,怎么就又错了。又反复看了书上的代码,确定地址的获取方式没有错,通过打印我发现地址确实有问题,端口和地址都不对。在网上搜了下 udp echo server的代码,用可以正常运行的代码和我的代码细细比对,终于发现了问题所在。问题就出在地址长度的初始化上,我一直以为recvfrom中的地址长度是值-返回模式,但是实际上这个值也是要在recvfrom中起作用的。如果这个值不正确,client_addr的值也是错误的,导致服务器无法正常的把数据发送到客户端。就酱。。。

socklen_t recv_addr_len = sizeof(client_addr); //正确的初始化方式
//socklen_t recv_addr_len; //错误的初始化方式
int rLen = recvfrom(serv_sock, buffer, MAX_LEN, MSG_WAITALL,
(struct sockaddr *)&client_addr, &recv_addr_len);

4. 参考

[3]  TCP/IP网络编程

 
 
 
 
 
 
 
 

网络编程-UDP echo server的更多相关文章

  1. Socket网络编程-UDP编程

    Socket网络编程-UDP编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.UDP编程概述 1>.UDP服务端编程流程 创建socket对象.socket.SOCK_ ...

  2. c/c++ 网络编程 UDP 设定MTU

    网络编程 UDP 设定MTU MTU(Maximun Transmisson Unit):一次送信的最大size. 在程序里动态改变MTU.注意:程序运行需要root权限. 程序运行的方法: sudo ...

  3. c/c++ 网络编程 UDP up/down 网卡

    网络编程 UDP up/down 网卡 在程序里动态改变网卡的状态.注意:程序运行需要root权限. 程序运行的方法: sudo ./a.out 1,关闭网卡 #include <stdio.h ...

  4. c/c++ 网络编程 UDP 改变网关和网卡名字

    网络编程 UDP 改变网关和网卡名字 在程序里动态改变网关和网卡名字 1,改变网卡名字 #include <stdio.h> #include <string.h> #incl ...

  5. c/c++ 网络编程 UDP 改变网卡的硬件地址

    网络编程 UDP 改变网卡的硬件地址 在程序里动态改变网卡的硬件地址 1,取得网卡的硬件地址 #include <stdio.h> #include <string.h> #i ...

  6. c/c++ 网络编程 UDP 改变IP地址

    网络编程 UDP 改变IP地址 在程序里动态改变主机的IP地址 1,改变ipv4的地址 #include <stdio.h> #include <string.h> #incl ...

  7. c/c++ 网络编程 UDP 用if_nameindex和ioctl取得主机网络信息

    网络编程 UDP 用if_nameindex和ioctl取得主机网络信息 getifaddrs函数取得的东西太多了,如果只想取得网卡名字和网卡编号可以用下面的2个函数. 1,if_nameindex ...

  8. c/c++ 网络编程 UDP 主机网络信息取得

    网络编程 UDP 主机网络信息取得 1,if_nametoindex 通过网卡名字取得网卡编号 2,if_indextoname 通过网卡编号取得网卡名字 #include <stdio.h&g ...

  9. c/c++ 网络编程 UDP 发送端 bind 作用

    网络编程 UDP 发送端 bind 作用 upd 发送端 调用bind函数的效果:把socket特定到一个指定的端口,如果不调用bind,内核会随机分配一个端口. upd 发送端 调用bind函数的目 ...

随机推荐

  1. 【LOJ】#3123. 「CTS2019 | CTSC2019」重复

    LOJ3123 60pts 正难则反,熟练转成总方案数减掉每个片段都大于等于s的字典序的方案 按照一般的套路建出kmp上每个点加一个字符的转移边的图(注意这个图开始字母必须是nxt链中下一个相邻的字符 ...

  2. [HNOI2008]越狱 题解

    题面: 我们知道:相邻房间的犯人的宗教相同的方案数=总方案数-相邻房间的犯人的宗教不相同的方案数: 那么所有方案数是m^n; 我们假设第一个房间有m中取值方案,而对于每个房间(非第一个)都有m-1个取 ...

  3. 剑指offer5:用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。

    1. 题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 2. 思想 (1)栈的特点是先进后出,而队列的特点是先进先出: (2)因此,入队列的情况和入栈的情 ...

  4. 基于全备份+binlog方式恢复数据

    基于全备份+binlog方式恢复数据 将bkxt从库的全备份在rescs5上恢复一份,用cmdb操作 恢复全备后执行如下操作 set global read_only=OFF; stop slave; ...

  5. RHEL8运维新利器--Cockpit使用方法

    在web浏览器中查看服务器并使用鼠标执行系统任务,很容易管理存储.配置网络和检查日志等操作. # 安装cockpit yum -y install cockpit # 启用cockpit system ...

  6. JDBC 24homework

    编写程序: 1. 创建商品信息表Goods(包含编号Code.名称Name.数量Number.单价Price) 2. 设计程序流程,由用户选择:插入.删除.修改.查询 程序效果如下: (1)根据提示输 ...

  7. 如果你的评论被WordPress的Akismet插件屏蔽,怎么解封?

    Akismet是Matt Mullenweg早期创办的一个项目,现在已经是Automattic公司的一个专注于剿杀垃圾评论的产品.在Wordpress用户中使用最多,z-blog也有用户在用,由于垃圾 ...

  8. dev listbox使用

    private void Init() { List<Funcation> data = new List<Funcation>(); data.Add(new Funcati ...

  9. BZOJ5017题解SNOI2017炸弹--玄学递推

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=5017 分析 老师讲课谈到了这道题,课上想出了个连边建图然后乱搞的操作,被老师钦定的递推方 ...

  10. HashMap工作原理总结

    看了不少关于HaskMap工作原理的博客,下面自己总结记录一下: 1.了解HashMap之前,需要知道Object类的两个方法:hashCode和equals: 默认实现方法: /** JNI,调用底 ...