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. 大数据备忘录———将数据从oracle导入impala中

    上周遇到了将数据从oracle导入到impala的问题,这个项目耽误了我近一周的时间,虽然是种种原因导致的,但是还是做个总结. 需求首先是跑数据,跑数据这个就不叙述,用的是公司的平台. 讲讲耽误我最久 ...

  2. PAT B1037 在霍格沃兹找零钱

    AC代码 #include <cstdio> #include <algorithm> using namespace std; char flag = 0; //判断付钱数是 ...

  3. STL set 常见用法详解

    <算法笔记>学习笔记 set 常见用法详解 set是一个内部自动有序且不含重复元素的容器 1. set 的定义 //单独定义一个set set<typename> name: ...

  4. WPF 异步加载窗体

    加载某个界面时,需要获取数据,而数据返回的时间比较长,这个时候可以异步加载界面. 1.在该窗体的加载事件(Load)中编写以下代码: new Thread(p=>{DataBinding();} ...

  5. 面试常考的js题目(三)

    1.查找两个节点的最近的一个共同父节点,可以包括节点自身 function commonParentNode(oNode1, oNode2) { if(oNode1.contains(oNode2)) ...

  6. zookeeper初识

    ZOOKEEPER是为分布式系统提供高性能的协调工具 角色: 1.领导者(leader):负责进行投票的发起和决议,更新系统状态2.学习者(learner):包括跟随者(follower)和观察者(o ...

  7. WebStorm 使用技巧

    常用快捷键 代码编辑 ctrl + d:复制行 ctrl + y:删除行 ctrl + x:剪切行 ctrl + shift + ↑: 行移动 ctrl + shift + enter: 换行 ctr ...

  8. WebStorm 启动时提示Failed to load JVM DLL

    环境:win7 64位:时间:2019-11-18 问题描述 启动webstorm 时提示failed to load JVM DLL 解决方法 启动时快捷方式要选到64位的exe

  9. CSS模块化:less

    less的安装与基本使用 less的语法及特性 一.本地使用less的方法 Less (Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言.是一种动态样式语言,属于c ...

  10. css3常用样式

    .box{ //改变轴的方向 flex-direction:column; //两端对齐 justify-content:space-between; //换行 flex-wrap: wrap; // ...