UNIX网络编程——基本UDP套接字编程

  • 概述
  • recvfrom 和 sendto函数
  • UDP 回射服务器程序:main 函数
  • UDP 回射服务器程序:dg_echo 函数
  • UDP 回射客户程序: main 函数
  • UDP 回射客户程序: dg_cli 函数
  • 数据报的丢失
  • 验证接收到的响应

概述

UDP是无连接不可靠的数据报协议。
使用UDP编写的一些常见的应用程序有:DNS(域名系统)、NFS(网络文件系统)和 SNMP(简单网络管理协议)。

recvfrom 和 sendto函数

#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void* buff, size_t nbytes, int flags, struct sockaddr* from, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void* buff, size_t nbytes, int flags,const struct sockaddr* to, socklen_t addrlen);均返回:若成功则为读或写的字节数,若出错则为-1

前三个参数 sockfd、buff 和 nbytes 等同于 read 和 write 函数的三个参数:描述符、指向读入或写成缓冲区的指针和读写字节数。

使用sendto、recvfrom发送和接收数据量为0的数据报是允许的。
recvfrom返回0,并不意味着收到对端FIN(sendto,recvfrom使用的场景下没有连接的概念)。

UDP 回射服务器程序:main 函数

#include  "unp.h"
int
main(int argc, char **argv)
{int sockfd;struct sockaddr_in servaddr, cliaddr;/*创建一个UDP套接字*/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); /*SERV_PORT 服务器的众所周知端口*/bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));/*调用函数 dg_echo 来执行服务器的处理工作*/dg_echo(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
}

UDP 回射服务器程序:dg_echo 函数

#include  "unp.h"
void
dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
{int n;socklen_t len;char mesg[MAXLINE];/*该函数是一个简单的循环,它使用 recvfrom 读入下一个到达服务器端口的数据报,再使用 sendto 把它发送回发送者*/for ( ; ;){len = clilen;n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);sendto(sockfd, mesg, n, 0, pcliaddr, len);}
}

图中总结了TCP客户/服务器在两个客户与服务器建立连接时情形。
服务器主机上有两个已连接套接字,其中每一个都有各自的套接字接收缓冲区。

下图展示了两个客户发送数据报到UDP服务器的情形。

UDP 回射客户程序: main 函数

#include  "unp.h"
int
main(int argc, char **argv)
{int sockfd;struct sockaddr_in servaddr;if (argc != 2)err_quit("usage: udpcli <IPaddress>");/*把服务器的IP地址和端口号填入一个IPv4的套接字地址结构*/bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = htons(SERV_PORT);inet_pton(AF_INET, argv[1], &servaddr.sin_addr);/*创建一个UDP套接字,然后调用dg_cli*/sockfd = socket(AF_INET, SOCK_DGRAM, 0);dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));exit(0);
}

UDP 回射客户程序: dg_cli 函数

#include  "unp.h"
void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{int n;char sendline[MAXLINE], recvline[MAXLINE + 1];/*客户处理循环中的四个步骤*//*使用 fgets 从标准输入读入一个文本行*/while (fgets(sendline, MAXLINE, fp) != NULL){/*使用 sendto 将该文本行发送给服务器*/sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);/*使用 recvfrom 读回服务器的回射*/n = recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL);recvline[n] = 0;       /*null terminate*//*使用 fputs 把回射的文本行显示到标准输出*/fputs(recvline, stdout);}
}

数据报的丢失

如果一个客户数据报丢失(如,被客户主机与服务器主机之间的某个路由器丢弃),客户将永远阻塞于 dg_cli 函数中的 recvfrom 调用,等待一个永远不会到达的服务器应答。

防止这样永久阻塞的一般方法是给客户的 recvfrom 调用设置一个超时。

验证接收到的响应

recvfrom 返回的IP地址(UDP数据报的源IP地址)不是我们所发送数据报的目的IP地址。

保证应答的源地址与请求的目的地址相同的方法:

  • 一个解决办法是:得到由 recvfrom 返回的IP地址后,客户通过在DNS中查找服务器主机的名字来验证该主机的域名(而不是它的IP地址)。
  • 另一个解决办法是:UDP服务器给服务器主机上配置的每个IP地址创建一个套接字,用bind捆绑每个IP地址到各自的套接字,然后在所有这些套接字上使用 select (等待其中任何一个变得可读),再从可读的套接字给出应答。

学习参考资料:

《UNIX网络编程 卷1:套接字联网API》 第3版

《UNIX网络编程 卷1:套接字联网API》学习笔记——基本UDP套接字编程相关推荐

  1. 《UNIX网络编程 卷1:套接字联网API(第3版)》——第2章 传输层:TCP、UDP和SCTP 2.1概述...

    本节书摘来自异步社区<UNIX网络编程 卷1:套接字联网API(第3版)>一书中的第2章,第2.1节,作者:[美]W. Richard Stevens , Bill Fenner , An ...

  2. 图灵社区 : 图书 : UNIX网络编程 卷1:套接字联网API(英文版•第3版)

    图灵社区 : 图书 : UNIX网络编程 卷1:套接字联网API(英文版•第3版) 图灵社区 : 图书 : UNIX网络编程 卷1:套接字联网API(英文版•第3版) UNIX网络编程 卷1:套接字联 ...

  3. UNIX网络编程.卷1,套接字联网API(第3版)(中文版)(Stevens经典著作,两位顶级网络编程专家应邀执笔修订)...

    UNIX网络编程.卷1,套接字联网API(第3版)(中文版)(Stevens经典著作,两位顶级网络编程专家应邀执笔修订) 基本信息 原书名: Unix Network Programming, Vol ...

  4. 《UNIX网络编程 卷1:套接字联网API》学习笔记——基本TCP套接字编程

    UNIX网络编程--基本TCP套接字编程 socket 函数 connect 函数 bind 函数 listen 函数 accept 函数 fork 和 exec 函数 并发服务器 close 函数 ...

  5. 《Unix网络编程卷1-套接字联网API》第一个例子编译 不通过问题解决

    <Unix网络编程卷1-套接字联网API>是本好书. 但是第一个例子不是很好编译. 需要如下步骤: 本人机器CentOS 5.4 1.下载源码 unpv13e解压到任意目录 然后按其rea ...

  6. [go学习笔记.第十六章.TCP编程] 3.项目-海量用户即时通讯系统-redis介入,用户登录,注册

    1.实现功能-完成用户登录 在redis手动添加测试用户,并画出示意图以及说明注意事项(后续通过程序注册用户) 如:输入用户名和密码,如果在redis中存在并正确,则登录,否则退出系统,并给出相应提示 ...

  7. 面向对象的编程思想写单片机程序——(3)学习笔记 之 程序分层、数据产生流程

    系列文章目录 面向对象的编程思想写单片机程序--(1)学习笔记 之 程序设计 面向对象的编程思想写单片机程序--(2)学习笔记 之 怎么抽象出结构体 面向对象的编程思想写单片机程序--(3)学习笔记 ...

  8. 《Unix网络编程卷1:套接字联网API》读书笔记

    第一部分:简介和TCP/IP 第1章:简介 第2章:传输层:TCP.UDP和SCTP TCP:传输控制协议,复杂.可靠.面向连接协议 UDP:用户数据报协议,简单.不可靠.无连接协议 SCTP:流控制 ...

  9. 《UNIX网络编程:套接字联网API》啃书笔记(第8UDP套接字编程、11章地址转换)

    基本UDP套接字编程 下图为UDP客户/服务器程序的函数调用: 注意客户不与服务器建立连接,而是只管使用sendto函数给服务器发送数据报,其中必须指定目的地的地址作为参数.类似的,服务器不接受来自客 ...

  10. TCP/IP网络编程 学习笔记_3 --给套接字分配IP地址和端口号

    IP地址和端口号 1,IP地址:为使计算机连接到网络并收发数据,必须为其分配IP地址.IP地址分为两类:IPv4(4字节地址族)和IPv6(16字节地址族).它们主要区别就是在表示IP地址所用的字节数 ...

最新文章

  1. 手机短信验证码真的安全吗?
  2. GPU — 体系结构
  3. springcloud全局过滤_微服务技术SpringCloud 互联网网站架构演变过程
  4. 小小军团获取服务器配置文件,小小军团2资源攻略 六种办法让你不再缺资源
  5. c语言程序中cost的作用,C语言考试题基础版(21页)-原创力文档
  6. 【转】图形流水线中坐标变换详解:模型矩阵、视角矩阵、投影矩阵
  7. mysql like in 数组_Web前端学习教程之常用的MySQL优化技巧
  8. ASP.NET【1】
  9. 7.Linux 高性能服务器编程 --- Linux 服务器程序规范
  10. (四)BP神经网络预测(上)
  11. Vivado 2020.1 仿真时卡在executing simulate step
  12. C语言实现链栈的创建、入栈、出栈、取栈顶、遍历......等基本操作(小白版详解)
  13. f和摄氏度怎么换算_华氏度和摄氏度的换算
  14. Namesilo转出域名到US Domain Center美国域名注册商
  15. 荣耀play4tpro有没有鸿蒙,荣耀Play4Tpro有没有耳机孔?
  16. 游戏思考30:技能碰撞检测分类枚举及逆水寒魔兽老兵服副本攻略(英雄武林风云录,后续更新舞阳城、扬州、清明等副本攻略)
  17. Ansible Ad—hoc 模式常用模块
  18. 【软考】--软考总结
  19. AcWing 125. 耍杂技的牛 (推公式)
  20. L1-043 阅览室 (20 分)andL1-048 矩阵A乘以B (15 分)

热门文章

  1. 苹果macOS 13 Ventura 5K原生动态壁纸
  2. Ubuntu18.04完全美化及常用软件安装 |QQ|TIM|微信|坚果云|备份
  3. python实现类似于visio_类似visio的软件有哪些?
  4. f分布表完整图a=0.01_QC七大手法(工具)完整版介绍
  5. 简单数论入门和基础数学知识(未完)
  6. 小米上市之后的危与机
  7. opendrive格式完全解析
  8. 如何更快通过BSCI审核
  9. scipy安装_4. Python--Scipy库(下/13-17)
  10. 建立在线社交网络中的关系权重模型