UDP套接字编程

时间:2022-12-01 20:01:09

典型的UDP客户/服务器程序的函数调用如下:

<unix网络编程>UDP套接字编程

1、缓冲区

<unix网络编程>UDP套接字编程

发送缓冲区用虚线表示,任何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的时候,它没有绑定一个本地端口,那么内核就在此时为它选择一个临时端口。

<unix网络编程>UDP套接字编程

上图中的圆点指明了客户发送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套接字编程的更多相关文章

  1. 【Unix网络编程】chapter8基本UDP套接字编程

    chapter8基本UDP套接字编程 8.1 概述 典型的UDP客户端/服务端的函数调用 8.2 recvfrom和sendto函数 #include <sys/socket.h> ssi ...

  2. 【Python网络编程】利用Python进行TCP、UDP套接字编程

    之前实现了Java版本的TCP和UDP套接字编程的例子,于是决定结合Python的学习做一个Python版本的套接字编程实验. 流程如下: 1.一台客户机从其标准输入(键盘)读入一行字符,并通过其套接 ...

  3. 探索UDP套接字编程

    UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务, ...

  4. 【转】 探索UDP套接字编程

    UDP和TCP处于同一层网络模型中,也就是运输层,基于二者之上的应用有很多,常见的基于TCP的有HTTP.Telnet等,基于UDP有DNS.NFS.SNMP等.UDP是无连接,不可靠的数据协议服务, ...

  5. 初探网络编程--TCP套接字编程演示

    今天看了一下<计算机网络:自顶向下方法>,也就是计算机网络的教材的应用层一章,决定实现以下后面的Java C/S应用程序的例子,用来演示TCP和UDP套接字编程. 程序流程如下: 1.一台 ...

  6. JavaTCP和UDP套接字编程

    在我们刚开始入门Java后端的时候可能你会觉得有点复杂,包含了很多杂七杂八的知识,例如文件上传下载,监听器,JDBC,请求重定向,请求转发等等(当然也没有很多),但是我们自己真正的去开发一个小型网站( ...

  7. TCP和UDP套接字编程 (java实现)

    在了解网络编程之前,我们先了解一下什么叫套接字 套接字即指同一台主机内应用层和运输层之间的接口 由于这个套接字是建立在网络上建立网络应用的可编程接口 因此也将套接字称为应用程序和网络之间的应用程序编程 ...

  8. 计算机网络实验 UDP套接字编程

    这是个傻瓜式操作教程 西科大计算机网络实验 UDP套接字编程 我用自己的Ubuntu16.04来举例,实验室的是虚拟机,差不多 只针对第三个题目,修改服务器来通过响应客户端发送的GetTime并发送给 ...

  9. UDP套接字编程 返回系统时间

    计算机网络实验 简单UDP套接字编程 这是学校老师自己改进了一点的题目.我预习了好久才搞明白,同学来问的时候,一大堆简单问题实在是不想回答...所以,这时候我觉得博客是个好东西! 我的任务是做客户端和 ...

随机推荐

  1. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架&quest;

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  2. OC ---- 字典集合 iOS学习-----细碎知识点总结

    实例方法的创建 NSDictionary *wukong = [[NSDictionary alloc] initWithObjectsAndKeys:", @"age" ...

  3. linux下查看进程状态

    1.查看进程的启动时间和执行时间 使用 ps 命令 :#ps -A -opid,stime,etime,args $ ps -A -opid,stime,etime,args PID STIME EL ...

  4. android开发系列之多线程

    今天在这篇博客里面,我只想谈谈自己对程序开发里面避无可避的一个问题-多线程的一些看法与思考. 其实说到多线程这个名称相信只要接触过软件这个行业的人都已经耳熟能详了,但是如果被问到到底什么才是多线程呢? ...

  5. Matlab 支持向量机(SVM)实现多分类

    1.首先,你需要安装完成Matlab. 2.将libsvm-3.17.zip和drtoolbox.tar文件解压到:libsvm-3.17文件夹和drtoolbox,并放到MATLAB的工具箱安装目录 ...

  6. HDU 5781 ATM Mechine 期望dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5781 ATM Mechine Time Limit: 6000/3000 MS (Java/Othe ...

  7. 数组&amp&semi;&amp&semi;函数数组

    数组:一次性定义多个同类型的变量,数组在 内存中存储空间必须是连续的(查询比较快)定义数组: int a[]; int[] a;分配空间: a=new int[5]; 自动为数组元素赋以默认值 a[0 ...

  8. 自动化脚本中click&lpar;&rpar;或sendKeys&lpar;&rpar;没有反应

    前提: 排除xpath引用错误或元素的xpath每次都不同的情形. 问题描述 自动化脚本中click()方法和sendKeys()方法报错, 返回异常InvocationTargetException ...

  9. JUC--ConcurrentHashMap

    HashMap HashTable HashTable锁住整个表 会存在复合操作上的问题“若不存则添加” “若存在则删除” 也是不安全的  效率低 ConcurrentHashMap:采用锁分段机制  ...

  10. sqlalchemy执行sql语句

    #删除user表中的所有数据,表中的自增字段又从默认值开始 session.execute("truncate table user")