IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> UDP socket 编程学习笔记 -> 正文阅读

[网络协议]UDP socket 编程学习笔记

UDP编程的基本流程

UDP是无连接、不可靠的数据报协议,不同于TCP的面向连接的可靠数据流。UDP编程常见的应用包括:DNS域名服务器、NFS网络文件系统、SNMP简单网络管理协议。

客户端不必与服务端建立连接,只需调用sendto函数向服务端发送数据。服务端不接受客户端的连接,只需在指定端口调用recvfrom函数接收客户端的数据即可。服务端调用recvfrom获取到客户端的地址,因此服务端可以把响应数据准确地发回给客户端。

UDP编程的基本流程如下所示:

服务端:socket()创建套接字 --> bind()绑定监听的地址、端口 --> recvfrom()等待接收客户端数据 --> sendto()发送应答数据给客户端

客户端:socket()创建套接字 --> sendto()向服务端发送数据 --> recvfrom()接收服务端应答数据 --> close()关闭套接字

recvfrom和sendto函数

#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);
- 返回值:接收数据的大小
- sockfd:socket描述符
- buff:接收数据的缓存
- nbytes:缓存大小
- flags:默认0
- from:客户端地址通用结构
- addrlen:客户端地址长度
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t addrlen);
- 返回值:发送数据的大小
- sockfd:socket描述符
- buff:发送数据的缓存
- nbytes:缓存大小
- flags:默认0
- to:服务端地址通用结构
- addrlen:服务端地址长度

UDP允许发送长度为0的数据,数据包只包含20字节IP头、8字节UDP头,recvfrom返回0,这是可以接收的,在TCP编程中read返回0意味着客户端发了FIN包。

每个UDP套接字都有一个接收缓冲区,收到的数据加入到缓冲区的尾部,调用recvfrom时,从缓冲区头部获取数据返回给应用程序。这里注意到一个和TCP的区别:TCP服务端每收到一个客户端的请求,就会从accept函数中返回一个新的fd,这个fd有自己的缓冲区,因此与每个客户端的连接都有自己独立的缓冲区,UDP不一样,所有的客户端数据共享一个服务端缓冲区。

UDP的connect函数

connect函数的作用

UDP调用connect函数有如下几个作用:

  • 告诉内核这个UDP套接字的数据包都发往connect绑定的目的地址,此时套接字可以调用send函数发送数据。也可以调用sendto函数,但是要将地址和长度都置为NULL。
  • 内核会过滤数据包,进程调用readrecvrecvmsg时,仅源地址为connect绑定的地址的数据包才返回给进程。
  • 进程可以多次调用connect以解绑并绑定一个不同的IP,这点和TCP套接字不同。
  • UDP套接字引发的异步错误会返回给进程。

connect解决UDP异步错误

UDP在给目标主机不存在的端口发送数据包时,目标主机内核会返回端口不可达的ICMP差错报文,通常情况下,这个报文仅达到发送主机的内核,并不会返回给应用程序。如果UDP调用connect,该ICMP差错报文会返回给调用程序。编写如下代码验证这个逻辑:

#include "unp.h"
int 
main(int argc, char **argv)
{
	struct sockaddr_in servaddr;
	socklen_t sock_len;
	int sockfd, i;
	char buff[MAX_LINE] = "hello world";
	bzero(&servaddr, sizeof(servaddr));
	
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(13);
	inet_pton(AF_INET, "192.168.157.144", &servaddr.sin_addr);
	sock_len = sizeof(struct sockaddr_in);
	i = connect(sockfd, (struct sockaddr *)&servaddr, sock_len);
	if (i < 0) {
		perror("connect fail \n");
		exit(0);
	}

	while (1) {
		i = send(sockfd, buff, strlen(buff), 0);
		if ( i < 0 )	{
			perror("send error\n");
			exit(0);
		}
	}
	return 0;
}

运行的结果如下所示:

[root@localhost sendto]# ./a.out
send error
: Connection refused

抓包可以看到:

21:17:07.345779 IP 192.168.157.144.43712 > 192.168.157.144.13: UDP, length 11
21:17:07.345789 IP 192.168.157.144 > 192.168.157.144: ICMP 192.168.157.144 udp port 13 unreachable, length 47

我的192.168.157.144是一个真实存在的主机,但是13端口并未开启。可以看到客户端收到ICMP的差错报文,send返回对应的错误码,但是这里有个地方要注意,ICMP报文返回需要时间,因此第一次send的时候没报错,后面再send,才会探测到错误。

修改代码,将目的地址改成不存在的主机IP,再次运行程序,虽然抓包可以看到IP不可达的ICMP差错报文,但是应用程序并不能感知到,从而可以推断出,仅目的主机IP可达,端口不可用的情况下,应用程序才能感知到。

通过抓包也可以看到,UDP调用connect并不会发送任何数据包,只是记录了目的地址。

connect对性能的提升

调用sendto函数发送UDP报文需要经过这样几个步骤:连接套接字–>发送一个报文–>断开套接字连接,发送第二个报文需要经过同样的步骤。调用connect后,无论发送几个报文,都不用重新连接和断开连接,提升了性能。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-02-19 01:33:50  更:2022-02-19 01:34:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 9:26:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码