全球知名电子商务网站统计番禺外贸网站建设
- 作者: 五速梦信息网
- 时间: 2026年03月21日 09:53
当前位置: 首页 > news >正文
全球知名电子商务网站统计,番禺外贸网站建设,网站建设蛋蛋28,建网站怎样往网站传视频目录
源IP地址和目的IP地址
源MAC地址和目的MAC地址
源端口号和目的端口号
端口号 VS 进程ID
TCP协议和UDP协议
网络字节序
字符串IP和整数IP相互转换
查看当前网络的状态
socket编程接口
socket常见API
创建套接字#xff08;socket#xff09; 绑定端口号socket 绑定端口号bind
发送数据send、sendto
接收数据 recv、recvfrom
监听套接字listen
接收请求accept 建立连接connect
sockaddr结构 源IP地址和目的IP地址
一、定义
源 IP 地址Source IP Address它是发送数据的设备如计算机、服务器等在网络中的唯一标识。就像是发送信件时的寄件人地址在网络通信中它用于标识数据的来源。目的 IP 地址Destination IP Address这是接收数据的设备在网络中的唯一标识类似于收件人地址。它告诉网络基础设施数据最终要传送到哪里。
二、在网络通信中的作用
数据传输导向在互联网这样庞大的网络环境中数据通过多个网络节点如路由器、交换机等进行传输。 源 IP 地址和目的 IP 地址就像指南针一样引导数据包从源设备通过复杂的网络路径最终到达目的设备。例如当你在浏览器中访问一个网站时你的计算机源设备的源 IP 地址和网站服务器目的设备的目的 IP 地址就确定了数据传输的起始点和终点。 路由决策依据路由器是网络中的关键设备用于将数据包从一个网络转发到另一个网络。 路由器根据数据包的目的 IP 地址来决定将其转发到哪个下一个网络节点。它会查询路由表路由表中记录了目的 IP 地址的网络范围以及对应的转发接口。例如如果一个数据包的目的 IP 地址属于某个特定的外部网络路由器就会将其从连接外部网络的接口转发出去。
三、举例说明
假设你在自己的家中通过 Wi - Fi 连接的笔记本电脑访问一家在线购物网站。你的笔记本电脑假设其 IP 地址是 192.168.1.10就是源设备192.168.1.10 是源 IP 地址。在线购物网站的服务器假设其 IP 地址是 104.27.189.99是目的设备104.27.189.99 是目的 IP 地址。当你在浏览器中输入网站的网址并发送请求时数据从你的笔记本电脑源出发。这个请求数据包包含了源 IP 地址192.168.1.10和目的 IP 地址104.27.189.99。数据包首先到达你家中的无线路由器路由器根据目的 IP 地址判断这个数据包需要发送到互联网服务提供商ISP的网络然后经过一系列的网络设备其他路由器等的转发最终到达购物网站的服务器目的。在整个过程中源 IP 地址和目的 IP 地址始终保持不变确保数据能够准确地发送和接收。
源MAC地址和目的MAC地址
源 MAC 地址Source MAC Address它是发送数据的网络设备如计算机网卡、网络交换机端口等在局域网LAN中的物理地址。MAC 地址也被称为硬件地址是由网络设备制造商固化在设备中的一个 48 位二进制数通常表示为 12 位的十六进制数例如 “00 - 1B - 44 - 11 - 3A - 0C”。这个地址在全球范围内是唯一的用于在局域网环境中标识数据的发送端。目的 MAC 地址Destination MAC Address它是接收数据的网络设备在局域网中的物理地址同样是一个 48 位的二进制数用于在局域网中标识数据的目标接收端。
有些数据的传输都是跨局域网的数据在传输过程中会经过若干个路由器最终才能到达对端主机。 源MAC地址和目的MAC地址是包含在链路层的报头当中的而MAC地址实际只在当前局域网内有效因此当数据跨网络到达另一个局域网时其源MAC地址和目的MAC地址就需要发生变化因此当数据达到路由器时路由器会将该数据当中链路层的报头去掉然后再重新封装一个报头此时该数据的源MAC地址和目的MAC地址就发生了变化。
因此数据在传输的过程中是有两套地址
一套是源IP地址和目的IP地址这两个地址在数据传输过程中基本是不会发生变化的存在一些特殊情况比如在数据传输过程中使用NET技术其源IP地址会发生变化但至少目的IP地址是不会变化的。另一套就是源MAC地址和目的MAC地址这两个地址是一直在发生变化的因为在数据传输的过程中路由器不断在进行解包和重新封装。
源端口号和目的端口号
两台主机之间通信的目的不仅仅是为了将数据发送给对端主机而是为了访问对端主机上的某个服务某个进程。比如我们在用百度搜索引擎进行搜索时不仅仅是想将我们的请求发送给对端服务器而是想访问对端服务器上部署的百度相关的搜索服务。 其实这种在网络中通信的本质就是进程间通信只是在不同的机器上进程间通信 跨网络的进程间通信我们把这种通信称做 套接字通信socket通信
socket通信本质上就是两个进程之间在进行通信只不过这里是跨网络的进程间通信。比如逛京东和刷抖音的动作实际就是手机上的京东进程和抖音进程在和对端服务器主机上的京东服务进程和抖音服务进程之间在进行通信。
因此进程间通信的方式除了管道、消息队列、信号量、共享内存等方式外还有套接字只不过前者是不跨网络的而后者是跨网络的。 那我们是如何去实现我们的 socket通信 的呢 先把数据能够到达对方的机器再在机器中能找到指定的进程同一台机器也可能会同时存在多个正在进行跨网络通信的进程因此当数据到达对端主机后必须要通过某种方法找到该主机上对应的服务进程 端口号port的作用实际就是标识一台主机上的一个进程
端口号是传输层协议的内容端口号是一个2字节16位的整数端口号用来标识一个进程告诉操作系统当前的这个数据要交给哪一个进程来处理一个端口号只能被一个进程占用
当数据在传输层进行封装时就会添加上对应源端口号和目的端口号的信息。这时通过源IP地址源端口号就能够在网络上唯一标识发送数据的进程通过目的IP地址目的端口号就能够在网络上唯一标识接收数据的进程此时就实现了跨网络的进程间通信。
注意
因为端口号是属于某台主机的所以端口号可以在两台不同的主机当中重复但是在同一台主机上进行网络通信的进程的端口号不能重复。所以一个进程可以绑定多个端口号但是一个端口号不能被多个进程同时绑定。
端口号 VS 进程ID 端口号port和 进程IDPID的作用都是标识一台主机上唯一的一个进程那在进行socket通信时为什么不直接用 进程ID 呢 进程IDPID是用来标识系统内所有进程的唯一性的它是属于系统级的概念端口号PORT是用来标识需要对外进行网络数据请求的进程的唯一性的它是属于网络的概念
一台机器上可能会有大量的进程但并不是所有的进程都要进行网络通信可能有很大一部分的进程是不需要进行网络通信的本地进程此时PID虽然也可以标识这些网络进程的唯一性但在该场景下就不太合适了进程管理 和 网络 解耦因为不同平台的 进程ID 的分配可能有所不同可能会出现不兼容的问题 底层如何通过端口号PORT找到对应进程的 机器底层采用哈希的方式建立了端口号和进程PID或PCB之间的映射关系当底层拿到端口号时就可以直接执行对应的哈希算法然后就能够找到该端口号对应的进程。
TCP协议和UDP协议
网络协议栈是贯穿整个体系结构的在应用层、操作系统层和驱动层各有一部分。当我们使用系统调用接口实现网络数据通信时面对的协议层就是传输层而传输层最典型的两种协议就是TCP协议和UDP协议 TCP协议 TCP协议叫做传输控制协议Transmission Control ProtocolTCP协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP协议是面向连接的如果两台主机之间想要进行数据传输那么必须要先建立连接当连接建立成功后才能进行数据传输。其次TCP协议是保证可靠的协议数据在传输过程中如果出现了丢包、乱序等情况TCP协议都有对应的解决方法。 UDP协议 UDP协议叫做用户数据报协议User Datagram ProtocolUDP协议是一种无需建立连接的、不可靠的、面向数据报的传输层通信协议。
使用UDP协议进行通信时无需建立连接如果两台主机之间想要进行数据传输那么直接将数据发送给对端主机就行了但这也就意味着UDP协议是不可靠的数据在传输过程中如果出现了丢包、乱序等情况UDP协议本身是不知道的。 既然UDP协议是不可靠的那为什么还要有UDP协议的存在 TCP协议可靠是需要我们做更多的工作的TCP协议虽然是一种可靠的传输协议但这一定意味着TCP协议在底层需要做更多的工作因此TCP协议底层的实现是比较复杂的我们不能只看到TCP协议面向连接可靠这一个特点我们也要能看到TCP协议对应的缺点。
UDP协议虽然是一种不可靠的传输协议但这一定意味着UDP协议在底层不需要做过多的工作因此UDP协议底层的实现一定比TCP协议要简单UDP协议虽然不可靠但是它能够快速的将数据发送给对方虽然在数据在传输的过程中可能会出错。
编写网络通信代码时具体采用TCP协议还是UDP协议完全取决于上层的应用场景。如果应用场景严格要求数据在传输过程中的可靠性此时我们就必须采用TCP协议如果应用场景允许数据在传输出现少量丢包那么我们肯定优先选择UDP协议因为UDP协议足够简单。
注意 一些优秀的网站在设计网络通信算法时会同时采用TCP协议和UDP协议当网络流畅时就使用UDP协议进行数据传输而当网速不好时就使用TCP协议进行数据传输此时就可以动态的调整后台数据通信的算法。
网络字节序
计算机在存储数据时是有大小端的概念的
大端模式 数据的高字节内容保存在内存的低地址处数据的低字节内容保存在内存的高地址处。小端模式 数据的高字节内容保存在内存的高地址处数据的低字节内容保存在内存的低地址处。
如果编写的程序只在本地机器上运行那么是不需要考虑大小端问题的因为同一台机器上的数据采用的存储方式都是一样的
但是如果涉及网络通信那就必须考虑大小端的问题否则对端主机识别出来的数据可能与发送端想要发送的数据是相反的。
例如现在两台主机之间在进行网络通信其中发送端是小端机而接收端是大端机。发送端将发送缓冲区中的数据按内存地址从低到高的顺序发出后接收端从网络中获取数据依次保存在接收缓冲区时也是按内存地址从低到高的顺序保存的就会出现想要发送的数据是相反的。
因此TCP/IP协议规定网络数据流采用大端字节序即低地址高字节。无论是大端机还是小端机都必须按照TCP/IP协议规定的网络字节序来发送和接收数据。
如果发送端是小端需要先将数据转成大端然后再发送到网络当中如果发送端是大端则可以直接进行发送如果接收端是小端需要先将接收到数据转成小端后再进行数据识别如果接收端是大端则可以直接进行数据识别 为什么网络字节序采用的是大端而不是小端 网络字节序采用的是大端而主机字节序一般采用的是小端那为什么网络字节序不采用小端呢如果网络字节序采用小端的话发送端和接收端在发生和接收数据时就不用进行大小端的转换了。
说法一 TCP在Unix时代就有了以前Unix机器都是大端机因此网络字节序也就采用的是大端但之后人们发现用小端能简化硬件设计所以现在主流的都是小端机但协议已经不好改了。 说法二 大端序更符合现代人的读写习惯。 网络字节序与主机字节序之间的转换 为使网络程序具有可移植性使同样的C代码在大端和小端计算机上编译后都能正常运行系统提供了四个函数可以通过调用以下库函数实现网络字节序和主机字节序之间的转换。
#include arpa/inet.h// 将一个 32 位的主机字节序整数转换为网络字节序
uint32_t htonl(uint32_t hostlong);// 将一个 16 位的主机字节序整数转换为网络字节序
uint16_t htons(uint16_t hostshort);// 将一个 32 位的网络字节序整数转换为主机字节序
uint32_t ntohl(uint32_t netlong);// 将一个 16 位的网络字节序整数转换为主机字节序
uint16_t ntohs(uint16_t netshort);
函数名当中的h表示主机字节序hostn表示网络字节序networkl表示32位长整数s表示16位短整数例如htonl表示将32位长整数从主机字节序转换为网络字节序如果主机是小端字节序则这些函数将参数做相应的大小端转换然后返回如果主机是大端字节序则这些函数不做任何转换将参数原封不动地返回
字符串IP和整数IP相互转换
IP地址的表现形式有两种
字符串IP类似于192.168.1.1这种字符串形式的IP地址叫做基于字符串的点分十进制IP地址整数IPIP地址在进行网络传输时所用的形式用一个32位的整数来表示IP地址 192.168.1.1为例192的二进制是11000000168的二进制是101010001的二进制是00000001连接起来得到11000000101010000000000100000001转换为十进制就是3232235777
字符串IP和整数IP的相互转换函数
// 字符串IP 转换成 整数IP
in_addr_t inet_addr(const char* cp);// 整数IP转换成字符串IP
char* inet_ntoa(struct in_addr in);
查看当前网络的状态
netstat 命令
netstat常用选项说明
-n直接使用IP地址而不通过域名服务器。-l显示监控中的服务器的Socket。-t显示TCP传输协议的连线状况。-u显示UDP传输协议的连线状况。-p显示正在使用Socket的程序识别码和程序名称 netstat命令显示的信息中
Proto 表示协议的类型Recv-Q 表示网络接收队列Send-Q 表示网络发送队列Local Address 表示本地地址Foreign Address 表示外部地址State 表示当前的状态PID 表示该进程的进程IDProgram name 表示该进程的程序名称。其中Foreign Address写成0.0.0.0:*表示任意IP地址、任意的端口号的程序都可以访问当前进程。
socket编程接口
socket常见API
头文件
#include sys/types.h
#include sys/socket.h
创建套接字TCP/UDP客户端服务器
int socket(int domain, int type, int protocol);绑定端口号TCP/UDP服务器
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);监听套接字TCP服务器
int listen(int sockfd, int backlog);接收请求TCP服务器
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);建立连接TCP客户端
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);发送数据
// 用于面向连接的套接字将数据发送到已连接的对等方
ssize_t send(int sockfd, const void *buf, size_t len, int flags);// 用于无连接的套接字或未连接的面向连接套接字将数据发送到指定地址
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); 接收数据
// 用于面向连接的套接字从已连接的对等方接收数据
ssize_t recv(int sockfd, void *buf, size_t len, int flags);// 用于无连接的套接字或未连接的面向连接套接字接收数据并获取发送方地址
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
关闭套接字
#include unistd.h
// 用于关闭套接字释放资源
int close(int fd);#include sys/socket.h
// 可以更灵活地关闭套接字的某些功能如只关闭发送或接收功能
int shutdown(int sockfd, int how); 创建套接字socket
创建套接字socket的函数如下
int socket(int domain, int type, int protocol);参数
domain创建套接字的域或者叫做协议家族也就是创建套接字的类型。该参数就相当于struct sockaddr结构的前16个位 如果是本地通信就设置为AF_UNIX如果是网络通信就设置为AF_INETIPv4或 AF_INET6IPv6。 type创建套接字时所需的服务类型。其中最常见的服务类型是SOCK_STREAM和SOCK_DGRAM 如果是基于UDP 的网络通信我们采用的就是SOCK_DGRAM叫做用户数据报服务如果是基于TCP 的网络通信我们采用的就是SOCK_STREAM叫做流式套接字提供的是流式服务。 protocol创建套接字的协议类别。你可以指明为TCP或UDP但该字段一般直接设置为0就可以了设置为0表示的就是默认此时会根据传入的前两个参数自动推导出你最终需要使用的是哪种协议。
返回值
套接字创建成功返回一个文件描述符创建失败返回-1同时错误码会被设置。 socket函数属于什么类型的接口 网络协议栈是分层的按照TCP/IP四层模型来说自顶向下依次是应用层、传输层、网络层和数据链路层。
我们现在所写的代码都叫做用户级代码也就是说我们是在应用层编写代码因此我们调用的实际是下三层的接口而传输层和网络层都是在操作系统内完成的也就意味着我们在应用层调用的接口都叫做系统调用接口 socket函数是被谁调用的 socket这个函数是被程序调用的但并不是被程序在编码上直接调用的而是程序编码形成的可执行程序运行起来变成进程当这个进程被CPU调度执行到socket函数时然后才会执行创建套接字的代码也就是说socket函数是被进程所调用的 socket函数底层如何实现的 socket函数是被进程所调用的而每一个进程在系统层面上都有一个进程地址空间PCBtask_struct、文件描述符表files_struct以及对应打开的各种文件。
而文件描述符表里面包含了一个数组fd_array其中数组中的0、1、2下标依次对应的就是标准输入、标准输出以及标准错误。 当我们调用socket函数创建套接字时实际相当于我们打开了一个“网络文件”打开后在内核层面上就形成了一个对应的struct file结构体同时该结构体被连入到了该进程对应的文件双链表并将该结构体的首地址填入到了fd_array数组当中下标为3的位置此时fd_array数组中下标为3的指针就指向了这个打开的“网络文件”最后3号文件描述符作为socket函数的返回值返回给了用户。 每一个struct file结构体中包含的就是对应打开文件各种信息比如文件的属性信息、操作方法以及文件缓冲区等
文件对应的属性在内核当中是由struct inode结构体来维护的文件对应的操作方法实际就是一堆的函数指针比如read*在内核当中就是由struct file_operations结构体来维护的文件缓冲区对于打开的普通文件来说对应的一般是磁盘但对于现在打开的“网络文件”来说这里的文件缓冲区对应的就是网卡 对于一般的普通文件来说当用户通过文件描述符将数据写到文件缓冲区然后再把数据刷到磁盘上就完成了数据的写入操作。
而对于现在socket函数打开的“网络文件”来说当用户将数据写到文件缓冲区后操作系统会定期将数据刷到网卡里面而网卡则是负责数据发送的因此数据最终就发送到了网络当中。 绑定端口号bind
绑定的函数叫做bind该函数的函数原型如下
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);参数
sockfd绑定的文件的文件描述符。也就是我们创建套接字时获取到的文件描述符addr网络相关的属性信息包括协议家族、IP地址、端口号等addrlen传入的addr结构体的长度
返回值
绑定成功返回0绑定失败返回-1同时错误码会被设置
在绑定时需要将网络相关的属性信息包括协议家族、IP地址、端口号等填充到一个结构体当中然后将该结构体作为bind函数的第二个参数进行传入这实际就是struct sockaddr_in结构体
struct sockaddr_in结构体当中的成员如下
sin_family表示协议家族 如果是本地通信就设置为 AF_UNIX如果是网络通信就设置为 AF_INETIPv4或 AF_INET6IPv6 sin_port表示端口号是一个16位的整数sin_addr表示IP地址是一个32位的整数 sin_addr结构体中就一个成员s_addr该成员就是一个32位的整数IP地址实际就是存储在这个整数当中的
发送数据send、sendto
send 用于面向连接的套接字将数据发送到已连接的对等方sendto 用于无连接的套接字或未连接的面向连接套接字将数据发送到指定地址
// 用于面向连接的套接字将数据发送到已连接的对等方
ssize_t send(int sockfd, const void *buf, size_t len, int flags);// 用于无连接的套接字或未连接的面向连接套接字将数据发送到指定地址
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
参数
sockfd套接字描述符。buf指向要发送数据的缓冲区的指针。len要发送数据的长度。flags控制发送操作的标志如 MSG_DONTWAIT 不阻塞等。dest_addr仅 sendto指向接收方地址的指针。addrlen仅 sendto接收方地址结构体的长度。
返回值
成功时返回实际发送的字节数。这个数字可能小于 len表示只发送了部分数据。这通常发生在以下情况 发送缓冲区已满无法一次性发送全部数据需要多次调用 send 函数将剩余数据发送完。 失败时返回 -1
接收数据 recv、recvfrom
recv 用于面向连接的套接字从已连接的对等方接收数据recvfrom 用于无连接的套接字或未连接的面向连接套接字接收数据并获取发送方地址
// 用于面向连接的套接字从已连接的对等方接收数据
ssize_t recv(int sockfd, void *buf, size_t len, int flags);// 用于无连接的套接字或未连接的面向连接套接字接收数据并获取发送方地址
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
参数
sockfd套接字描述符。buf指向接收数据的缓冲区的指针。len缓冲区的长度。flags控制接收操作的标志如 MSG_DONTWAIT 不阻塞等。src_addr仅 recvfrom指向发送方地址的指针。addrlen仅 recvfrom指向发送方地址结构体长度的指针。
返回值
成功时返回接收到的字节数如果连接已经正常关闭返回值为 0表示对方已关闭连接。失败时返回 -1
监听套接字listen
int listen(int sockfd, int backlog);
参数
sockfd 这是一个已经创建并绑定了本地地址的套接字描述符。套接字通常由socket函数创建例如int sockfd socket(AF_INET, SOCK_STREAM, 0);。对于AF_INET表示使用 IPv4 协议族SOCK_STREAM表示使用面向连接的 TCP 套接字。在调用listen之前该套接字需要使用bind函数绑定到一个本地地址以便让服务器程序在特定的地址和端口上监听客户端的连接请求。 backlog 它指定了连接请求队列的最大长度。当多个客户端同时尝试连接服务器时操作系统会将这些连接请求存储在一个队列中等待服务器处理。例如将backlog设置为 10意味着最多可以有 10 个未处理的连接请求在队列中等待服务器的accept操作。设置这个值时需要权衡资源利用和性能过小可能导致连接请求丢失过大可能会占用过多的系统资源。
返回值
成功返回 0表示套接字已成功进入监听状态服务器可以接收客户端的连接请求。失败返回 -1并设置相应的错误代码。可以使用perror函数来输出具体的错误信息。
接收请求accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd 这是一个已经处于监听状态的套接字描述符通常是由socket函数创建并经过bind和listen函数处理后进入监听状态的套接字。例如int sockfd socket(AF_INET, SOCK_STREAM, 0);并且经过listen(sockfd, backlog);处理。它代表服务器端的监听套接字通过该套接字接收客户端的连接请求。 addr 这是一个指向struct sockaddr或其变体如struct sockaddr_in对于 IPv4的指针用于存储客户端的地址信息。当accept成功返回时这个指针所指向的结构体将被填充为发起连接请求的客户端的地址信息包括客户端的 IP 地址和端口号。如果不关心客户端的地址信息可以将此参数设置为NULL。 addrlen 这是一个指向socklen_t类型的指针它表示addr参数所指向的结构体的长度。在调用accept之前需要将其初始化为addr所指向结构体的大小例如对于struct sockaddr_in可以使用sizeof(struct sockaddr_in)。在accept返回后addrlen的值可能会被修改为实际存储客户端地址信息的长度尤其是在使用可变长度地址结构体时。 返回值
成功 accept函数会返回一个新的套接字描述符这个新的套接字将用于和客户端进行通信。服务器可以使用这个新的套接字进行读写操作例如使用send和recv函数发送和接收数据。 失败 如果accept调用失败它将返回 -1并设置相应的错误代码。可以使用perror函数来输出具体的错误信息常见的错误可能包括系统资源不足、没有连接请求等待等。 建立连接connect
int connect(int sockfd, const struct sockaddr addr, socklen_t addrlen);
sockfd这是一个已经创建的客户端套接字描述符addr这是一个指向struct sockaddr或其变体如struct sockaddr_in对于 IPv4 或struct sockaddr_in6对于 IPv6的指针包含了服务器的地址信息。addrlen这是addr所指向的结构体的长度通常使用sizeof操作符获取。
返回值
成功 如果connect函数调用成功它将返回 0表示已经成功连接到服务器。一旦连接成功客户端就可以使用这个套接字发送和接收数据例如使用send和recv函数。 失败 如果connect函数调用失败它将返回 -1并设置相应的错误代码。可以使用perror函数输出具体的错误信息。常见的错误可能包括服务器不可达、连接超时、服务器未监听等。
sockaddr结构
套接字不仅支持跨网络的进程间通信还支持本地的进程间通信域间套接字。在进行跨网络通信时我们需要传递的端口号和IP地址而本地通信则不需要因此套接字提供了sockaddr_in结构体和sockaddr_un结构体
sockaddr_in 结构体是用于跨网络通信的sockaddr_un 结构体是用于本地通信的
为了让套接字的网络通信和本地通信能够使用同一套函数接口于是就出现了sockeaddr结构体该结构体与sockaddr_in和sockaddr_un的结构都不相同但这三个结构体头部的16个比特位都是一样的这个字段叫做协议家族 注意 实际我们在进行网络通信时定义的还是sockaddr_in这样的结构体只不过在传参时需要将该结构体的地址类型进行强转为sockaddr 了。 为什么没有用 void* 代替 struct sockaddr* 类型 我们可以将这些函数的 struct sockaddr* 参数类型改为 void*此时在函数内部也可以直接指定提取头部的16个比特位进行识别最终也能够判断是需要进行网络通信还是本地通信那为什么还要设计出sockaddr这样的结构呢
实际在设计这一套网络接口的时候C语言还不支持void*于是就设计出了sockaddr这样的解决方案。并且在C语言支持了void*之后也没有将它改回来因为这些接口是系统接口系统接口是所有上层软件接口的基石系统接口是不能轻易更改的否则引发的后果是不可想的这也就是为什么现在依旧保留sockaddr结构的原因。
- 上一篇: 全球网站制作做网站虚拟主机价格
- 下一篇: 全球著名科技网站建设简易电子商务网站流程
相关文章
-
全球网站制作做网站虚拟主机价格
全球网站制作做网站虚拟主机价格
- 技术栈
- 2026年03月21日
-
全球设计网分站软件工程师需要考什么证
全球设计网分站软件工程师需要考什么证
- 技术栈
- 2026年03月21日
-
全屏自适应网站模板品牌网站建设十小蝌蚪
全屏自适应网站模板品牌网站建设十小蝌蚪
- 技术栈
- 2026年03月21日
-
全球著名科技网站建设简易电子商务网站流程
全球著名科技网站建设简易电子商务网站流程
- 技术栈
- 2026年03月21日
-
全球最大的网站建设外包网没备案的网站收录
全球最大的网站建设外包网没备案的网站收录
- 技术栈
- 2026年03月21日
-
全世界做会展介绍的网站排名免费建站网站一级123456
全世界做会展介绍的网站排名免费建站网站一级123456
- 技术栈
- 2026年03月21日






