<unix网络编程>UDP套接字编程
典型的UDP客户/服务器程序的函数调用如下:

1、缓冲区

发送缓冲区用虚线表示,任何UDP套接字都有发送缓冲区,不过该缓冲区仅能表示写到该套接字的UDP数据报的上限。如果应用进程写一个大于套接字缓冲区大小的数据报,将会返回该进程一个EMSGSIZE错误。从写一个UDP套接字的write调用成功返回,表示所写的数据报或其所有的片段已被加入到数据链路层的输出队列。如果该队列没有足够的空间存放该数据报或它的某个片段,内核通常会返回一个ENOBUFS错误给它的应用进程。
2、相关函数
- recvfrom()和sendto()
ssize_t sendto (int sockfd, void *buf, size_t bytes,
int flags, const struct sockaddr* to,
socklen_t *addrlen);
ssize_t recvfrom (int sockfd, void *buf, size_t nbytes,
int flags, struct sockaddr* from,
socklen_t *addrlen);
- recvfrom():
- from:指向一个将由该函数在返回时填写数据报发送者协议地址的套接字地址结构
- addrlen:在from指向的套接字结构中的填写的字节数。
- sendto():
- to:指向一个含有数据报接收者的协议地址的套接字地址结构
- addrlen:to指向的套接字地址结构大小。
recvfrom()的from参数可以是一个空指针,那么相应的长度参数也应该是一个空指针,表示不在意数据发送者的协议地址。写一个长度为0的数据报是可行的,在UDP情况下,这会形成一个只包含一个IP首部(对于IPv4是20字节,对于IPv6而言是40字节)和一个8字节UDP首部而没有数据的IP数据报。意味着对于数据报协议,recvfrom返回0值是可以接受的,不像TCP套接字上read返回0值那样表示对端已关闭连接。既然UDP是无连接的,因此也就没有诸如关闭一个UDP连接之类的事情。
接收缓冲:UDP中隐有排队现象发生。事实上每个UDP套接字都有一个接受缓冲区,到达该套接字的每个数据报都进入这个套接字接受缓冲区 。当进程调用recvfrom的时候,缓冲区的下一个数据报以FIFO的顺序回传给进程。这样,在进程能够读该套接字中任何已排好队的数据报之前,如果有多个数据报到达该套接字,那么相继到达的数据报仅仅加到该套接字的接收缓冲区中。这个缓冲区的大小是有限的。
对于一个UDP套接字,如果其进程首次调用sendto的时候,它没有绑定一个本地端口,那么内核就在此时为它选择一个临时端口。

上图中的圆点指明了客户发送UDP数据报的时候,必须指定或选择的四个值
- 客户必须给sendto调用指定的服务器的IP地址和端口
- 客户的IP地址和端口号可以指定也可以不指定。
- 如果客户没有捆绑具体的IP和端口号,内核会自动选择:
- IP地址却可以随客户发送的每个UDP数据报而变动
- 临时端口是在第一次调用sendto时一次性选定,不能改变
- 如果客户绑定了一个IP地址
- 在这种情况下,如果内核决定外出数据报必须从另一个数据链路发出,IP数据报将会包含一个不同于外出链路IP地址的源IP地址
在一个未绑定端口号和IP地址的UDP套接字上调用connect的时候,会给套接字指派一个IP地址和临时端口
TCP和UDP服务器指定获取源IP,源端口号,目的IP和目的端口号的方法:
| 来自客户端的IP数据报 | TCP服务端 | UDP服务端 |
| 源IP地址 | accept | recvfrom |
| 源端口号 | accept | recvfrom |
| 目的IP地址 | getsockname | recvmsg |
| 目的端口号 | getsockname | getsockname |
- 非连接状态下,同一套接字可以给多个服务器发送数据报
- 服务器上的同一个套接字可以从若干不同客户端接收数据
2、连接的UDP套接字
#include <sys/socket.h> itn connect(itn sockfd, const struct sockaddr*servaddr,socklen_t addrlen);
- sockfd,客户端套接字描述符
- servaddr,包含服务器IP地址和端口号的套接字地址结构
- addrlen,套接字地址结构的大小
给UDP套接字调用connect并不会像TCP一样出发三次握手,内核只是检查是否存在立即可知的错误,记录对端的IP地址和端口号,然后立即返回
已连接的UDP套接字和未连接的UDP套接字存在3个不同:
- 限制了一个已连接套接字能且仅能与一个对端交换数据
- 不能再给输出操作指定目的IP地址和端口号,即不使用sendto而改用write或send
- 不必使用recvfrom以获悉数据报的发送者,而改用read、recv或recvmsg
- 接收异步错误
- 由已连接UDP套接字引发的异步错误会返回给它们所在的进程。未连接时不接收任何异步错误
一个拥有已连接UDP套接字的进程,可出于下列2个目的再次调用connect:
- 指定新的IP地址和端口号
- 断开套接字:调用connect时,把套接字地址结构的地址族成员设置为AF_UNSPEC。
TCP要再次调用connect必须先close套接字然后再重新调用socket创建套接字描述符。
连接与不连接的性能:当应用进程在一个未连接的UDP套接字上调用sendto时,源自Berkeley的内核暂时连接该套接字,发送数据报,然后断开该连接。因此,当应用进程要给同一目的地址发送多个数据报时,使用连接套接字可以获得更高的效率
<unix网络编程>UDP套接字编程的更多相关文章
- 《Unix 网络编程》08:基本UDP套接字编程
基本UDP套接字编程 系列文章导航:<Unix 网络编程>笔记 UDP 概述 流程图 recvfrom 和 sendto #include <sys/socket.h> ssi ...
- 【Unix网络编程】chapter8基本UDP套接字编程
chapter8基本UDP套接字编程 8.1 概述 典型的UDP客户端/服务端的函数调用 8.2 recvfrom和sendto函数 #include <sys/socket.h> ssi ...
- 【Python网络编程】利用Python进行TCP、UDP套接字编程
之前实现了Java版本的TCP和UDP套接字编程的例子,于是决定结合Python的学习做一个Python版本的套接字编程实验. 流程如下: 1.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接 ...
- 探索UDP套接字编程
UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务, ...
- 【转】 探索UDP套接字编程
UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务, ...
- 初探网络编程--TCP套接字编程演示
今天看了一下<计算机网络:自顶向下方法>,也就是计算机网络的教材的应用层一章,决定实现以下后面的Java C/S应用程序的例子,用来演示TCP和UDP套接字编程. 程序流程如下: 1.一台 ...
- JavaTCP和UDP套接字编程
在我们刚开始入门Java后端的时候可能你会觉得有点复杂,包含了很多杂七杂八的知识,例如文件上传下载,监听器,JDBC,请求重定向,请求转发等等(当然也没有很多),但是我们自己真正的去开发一个小型网站( ...
- TCP和UDP套接字编程 (java实现)
在了解网络编程之前,我们先了解一下什么叫套接字 套接字即指同一台主机内应用层和运输层之间的接口 由于这个套接字是建立在网络上建立网络应用的可编程接口 因此也将套接字称为应用程序和网络之间的应用程序编程 ...
- 计算机网络实验 UDP套接字编程
这是个傻瓜式操作教程 西科大计算机网络实验 UDP套接字编程 我用自己的Ubuntu16.04来举例,实验室的是虚拟机,差不多 只针对第三个题目,修改服务器来通过响应客户端发送的GetTime并发送给 ...
随机推荐
- SAP MM 按采购订单查询付款信息的报表?
SAP MM 按采购订单查询付款信息的报表? 上午给P3项目采购部门用户做了一个采购相关的报表的培训.培训过程中,客户的采购部门经理提出了一个问题:有没有报表能查询到各个采购订单的付款情况,显示采购订 ...
- DotNetBar的窗口样式丢失
DotNetBar的窗口样式丢失 C# 调用DotNetBar很方便,将DevComponents.DotNetBar2.dll和DevComponents.DotNetBar.Design.dll放 ...
- 如何查看程序所占端口号和IP
如何查看程序所占端口号和IP 一个软件可能占用多个端口拥有多个目标IP,下面以FQ工具Lantern为例,说明端口查看方法: 1.借助第三方软件查看 如果你电脑上安装了360等优化工具,可能会自带查看 ...
- Python3.6 下 安装MySql
https://pypi.python.org/pypi/mysqlclient/1.3.10 该网页下下载 Python-3.5及上版本的扩展的mysql驱动. 下载的是一个.whl文件,下载目录为 ...
- C#:关于C#4中IEnumerable<out T>的理解
IEnumerable<out T>这个接口非常常见,它是最基础的泛型集合接口,表示可迭代的项的序列. 但是奇怪的是为什么泛型参数要带一个“out”? 经过一番资料查阅后,发现此“out” ...
- git 入门教程之实战 git
实战 git git 是一款分布式版本控制系统,可以简单概括: 不要把鸡蛋放在一个篮子里,你的一举一动都在监视中. 实战场景 你作为某项目的其中一员或者负责人,和小伙伴们一起开发,大家既有着各自分工互 ...
- springboot 学习之路 4(日志输出)
目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...
- redis搭建主从(1主2从)
一,先附上配置文件 1,master(6379.conf)上面的配置文件 daemonize yes pidfile /usr/local/redis/logs/redis_6379.pid port ...
- Sql查询今天、本周和本月的记录(时间字段为时间戳)
工作中遇到的问题,小结一下 查询今日添加的记录: select * from [表名] where datediff(day,CONVERT(VARCHAR(20),DATEADD(SECOND,[时 ...
- 使用Java+MySQL+Apache开发后台项目(一)
做前端开发的人越来越多,后端维护的人才越来越稀缺,这种趋势正在慢慢扩展.像我这种人总喜欢反其道而行之,做后端开发的人虽然减少了,但是工作量和工作资质都要求的更高了,随着人工智能的发展,需要后台处理的数 ...