【计算机网络】详解UDP套接字网络字节序IP地址端口号

devtools/2024/9/25 15:00:16/

一、网络字节序

       我们已经知道, 内存中的多字节数据相对于内存地址有大端和小端之分, 磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分, 网络数据流同样有大端小端之分.
  • 发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出;
  • 接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存;因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址.
  • TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节.不管这台主机是大端机还是小端机, 都会按照这个TCP/IP规定的网络字节序来发送/接收数据;如果当前发送主机是小端, 就需要先将数据转成大端; 否则就忽略, 直接发送即可。
        为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。

         这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整数。 例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。 如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回; 如果主机是大端字节序,这些 函数不做转换,将参数原封不动地返回。

二、IP地址和端口号

        IP地址是在IP协议中, 用来标识网络中不同主机的地址; 对于IPv4来说, IP地址是一个4字节, 32位的整数; 我们通常也使用 "点分十进制" 的字符串表示IP地址, 例如 192.168.0.1 ; 用点分割的每一个数字表示一个 字节, 范围是 0 - 255; 

        端口号是一个2字节16位的整数;端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理;IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;一个端口号只能被一个进程占用。

三、socket

        socket编程是有不同种类的,有的是专门用来进行本地通信的(unix socket),有的是专门进行跨网络通信的(inet socket),有的是用来进行网络管理的(raw socket)。为了统一调用接口,设计者设计出了sockaddr结构。

3.1、sockaddr结构

        socket编程既可以用来进行网络通信也可以用来进行本地通信。下面是用来进行网络通信和本地通信不同的sockaddr结构体。sockaddr前两个字节表明自身类型。

 3.2、UDPsocket常见API

// 创建 socket 文件描述符 (TCP/UDP, 客户端 + 服务器 )
int socket(int domain, int type, int protocol);
// 绑定端口号 (TCP/UDP, 服务器 )
int bind(int socket, const struct sockaddr *address, socklen_t address_len);
//接收信息
ssize_t recvfrom(int sockfd,const void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
//发送信息
ssize_t sendto (int sockfd,const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t *addrlen);

3.2.1、 socket

         socket()返回一个文件描述符,domain表示套接字的类型,type表示套接字的服务类型,第三个参数填0,参数填好就能确定是udp套接字。创建失败-1被返回,错误码被设置。socket就相当于在进程内部帮我们打开了一个文件。远端机器要想办法找到这个文件,所以就有了bind。

3.2.2、bind

        本地打开的文件sockfd要与网络信息sockaddr关联起来。bind第一个参数就是socket的返回值。第二个参数addr有三个要填充的字段。sin_family表示通信类型,网络通信填写AF_INET,sin_addr表示ip地址,sin_port表示端口号。端口号可以由外部传入,未来是要通过网络告知对方的服务进程的。要经过网络传输就要将端口号从主机序列转为网络序列。ip地址也要从主机序列转为网络序列,使用inet_addr函数可以一步到位将string类型的ip转化为4字节ip并转化为网络序列。

        注意点:我们不能绑定一个公网IP,或是任意一个确定的IP,因为一台机器上可能存在不同的IP地址,如果绑定了确定的IP地址,就有可能导致远端服务无法访问的情况。服务器在绑定IP地址时,IP地址可以直接填0,表示任意地址绑定(计算机中所有的IP都绑定了)

3.2.3、recvfrom

        recvfrom第二个参数buf是一个输出型参数,将来从sockfd中读到的数据就会放到buf中,第三个参数len表示希望从网络套接字中读取的数据的长度,返回值为实际读到的数据长度,读取方式flags默认设为0,后两个参数为输出型参数,可以用来通信对方的信息。

3.2.4、sendto

        sendto第二个参数表示要发送的字符串数组,第三个参数为字符串数组的长度,flags填0,后两个参数为通信对方的信息。

四、了解本地环回

        本地环回:可以实现本地通信,通常用来进行代码测试。客户端不需要显式地绑定端口号,因为有可能会引起端口号冲突,当client第一次向服务端发送信息时,OS会自动为客户端绑定端口号。


http://www.ppmy.cn/devtools/117013.html

相关文章

一个使用 PyTorch 实现的中文聊天机器人对话生成模型916

这是一个使用 PyTorch 实现的中文聊天机器人对话生成模型。 1数据准备 代码假设有两个文件:questions.txt 和 answers.txt,它们分别包含输入和输出序列。 load_data 函数读取这些文件并返回一个句子列表。 build_vocab 函数通过遍历句子来构建词汇表字…

数据库连接池

1、连接池介绍 1、操作数据库都需要创建连接,操作完成还需要关闭连接 2、创建连接和关闭连接需要可能比执行sql需要的时间都长 3、一个网站需要高频繁的访问数据库,如果短时间频繁的访问数据库服务器,就容易造成服务器的宕机,即…

Nexus学习

系列文章目录 第一章 基础知识、数据类型学习 第二章 万年历项目 第三章 代码逻辑训练习题 第四章 方法、数组学习 第五章 图书管理系统项目 第六章 面向对象编程:封装、继承、多态学习 第七章 封装继承多态习题 第八章 常用类、包装类、异常处理机制学习 第九章 集…

数据结构---二叉搜索树(二叉排序树)

什么是二叉排序树 二叉搜索树又是二叉排序树,当我们的是一颗空树或者具有以下性质时: 左子树不为空,左子树上的值都小于我们的根节点上的值。右子树不为空时,右子树上的值都大于我们的根节点上的值左右子树都是二叉搜索树&#…

Java笔试面试题AI答之设计模式(2)

文章目录 6. 什么是单例模式,以及他解决的问题,应用的环境 ?解决的问题应用的环境实现方式 7. 什么是工厂模式,以及他解决的问题,应用的环境 ?工厂模式简述工厂模式解决的问题工厂模式的应用环境工厂模式的…

ESP32-WROOM-32 [创建AP站点-客户端-TCP透传]

简介 基于ESP32-WROOM-32 开篇(刚买), 本篇讲的是基于固件 ESP32-WROOM-32-AT-V3.4.0.0(内含用户指南, 有AT指令说明)的TCP透传设置与使用 设备连接 TTL转USB线, 接ESP32 板 的 GND,RX2, TX2 指令介绍 注意,下面指…

Python知识点:如何使用Python与.NET进行互操作(IronPython)

开篇,先说一个好消息,截止到2025年1月1日前,翻到文末找到我,赠送定制版的开题报告和任务书,先到先得!过期不候! IronPython 是一个开源的 Python 实现,它运行在 .NET 平台上&#xf…

用python给markdown文档加空行

在文本格式化过程中,我们通常会在行与行之间添加一个空行,以提升文档的阅读体验,使其外观更加整洁。 若您处理的文档篇幅较短,手动添加空行也是一个可行的选择。 此外,为了简化这一过程,您可以采用以下Pyt…