Unix网络编程

一个简单的时间获取客户端程序

把上面的ipv4协议换成ipv6,加粗字体需要替换

一个简单的时间获取服务器程序

accept函数

1. 默认行为(阻塞模式)

当你创建一个 socket,使用 bindlisten 后,默认的套接字是阻塞的。此时调用 accept

  • 如果已完成连接队列 (已完成三次握手的连接)为空,accept阻塞当前线程,直到有新的客户端连接到来。

  • 当有新连接时,accept 返回一个新的已连接套接字(connected socket)。

2. 非阻塞模式

你可以通过以下方式将监听套接字设置为非阻塞 ,此时 accept 变为非阻塞:

  • 如果连接队列为空,accept 不会等待,而是立即返回 -1,并设置 errnoEAGAINEWOULDBLOCK

  • 在 Linux 下 ,你还可以在创建 socket 时使用 SOCK_NONBLOCK 标志,或者使用 fcntl 设置 O_NONBLOCK 属性。

UDP套接字

客户端可以通过同一个套接字发送给不同的服务端

这是因为 UDP 是无连接的协议 ,UDP 套接字本身不维护与对端之间的固定连接状态。你可以把一个 UDP 套接字想象成一个"邮箱":它只需要绑定到本地地址和端口,之后每次发送数据时,在 sendtosendmsg 调用中明确指定目标地址(IP + 端口),就可以将数据发往任意不同的服务端。


具体原因

  1. 无连接特性

    UDP 在传输层不建立连接,每个数据报都是独立发送的。内核只根据你提供的目标地址来封装 IP 头和 UDP 头,不需要像 TCP 那样先建立连接并维护状态。

  2. 套接字与目标地址的分离

    • TCP 中,一个套接字一旦通过 connect 连接到某个服务端,内核就会为该套接字固定对端的 IP 和端口,之后只能用 send/write 发送,不能再改变目标。

    • UDP 中,即使你调用了 connect(UDP 的 connect 只是在内核中缓存了默认目标地址,并不建立真实连接),你仍然可以使用 sendto 覆盖该默认目标,发送到其他地址。未调用 connect 的 UDP 套接字更是完全自由。

  3. 内核的实现

    UDP 套接字在内核中只记录本地地址和端口,发送数据时,从用户空间传入的目标地址被直接用于构造数据报。内核不会因为发送到不同服务端而创建新的套接字或改变原有套接字的状态。

UDP可以不使用connect

UDP 使用 sendtoconnect 的区别

特性 不使用 connect 使用 connect
发送方式 必须用 sendto 指定目标地址 可以用 send / write(目标地址已缓存)
接收方式 recvfrom 获取发送方地址 可以用 recv / read,但 recvfrom 也能用
地址绑定 每次发送都指定目标,可发往不同地址 只与一个固定地址"绑定",但可以通过 sendto 覆盖
内核开销 每次发送都需复制目标地址 内核缓存目标地址,减少一次地址复制
错误报告 异步错误(如端口不可达)可能延迟返回 同步错误,部分错误会立即返回给 send

为什么不使用 connect 更灵活?

因为 UDP 是无连接的,一个 UDP 套接字可以在不同时间向不同的服务端发送数据,无需重新创建套接字。这在需要与多个对端通信的场景(如 DNS 客户端、P2P 应用)中非常方便。

那什么时候用 connect

  1. 只与一个固定服务端通信(如传统的 UDP 客户端/服务器模型)。

  2. 希望简化代码send/recvsendto/recvfrom 少写参数。

  3. 需要接收异步错误connect 后,某些错误(如 ICMP 端口不可达)会直接传递给套接字,而不是在后续的 sendto 中才被感知。

  4. 性能敏感场景:减少内核中每次发送时的地址处理开销。

注意:connect 并不改变 UDP 的无连接本质

即使对一个 UDP 套接字调用了 connect,你依然可以通过 sendto 发往其他地址(除非设置 IP_FREEBIND 等特殊选项)。但通常不建议混合使用,以免造成混淆。

TCP套接字

1. 流量控制(Flow Control)

  • 目的:防止发送方发送数据过快,导致接收方缓冲区溢出而丢包。

  • 实现机制滑动窗口。接收方通过 TCP 报文头中的"窗口"字段告知发送方自己当前还能接收多少字节的数据(可用窗口大小)。发送方根据这个窗口值动态调整发送速率。

  • 特点:这是端到端的控制,确保发送方的发送速度匹配接收方的处理能力。


2. 排序(Ordering / Sequencing)

  • 目的:保证数据在到达接收端后,能按照发送时的顺序重组。

  • 实现机制序列号。TCP 将应用层交付的数据分割成若干段(Segment),并为每个字节分配一个序号。接收方根据序号将乱序到达的数据重新排序,并去除重复数据。

  • 特点:这是 TCP 可靠传输的重要保障,解决了 IP 层可能产生的乱序和重复问题。


3. 全双工(Full-Duplex)

  • 含义 :TCP 连接允许数据在两个方向上同时独立地传输。即 A 向 B 发送数据的同时,B 也可以向 A 发送数据。

  • 实现方式:每个 TCP 连接在双方各自维护一个发送缓冲区和接收缓冲区。两个方向的传输互不干扰,由独立的序列号空间和窗口大小分别管理。

  • 优势:提高了交互式应用的响应速度,例如在 HTTP 请求/响应、远程登录等场景下,双方可以同时发送数据。

三次握手

上面这个打电话的例子非常好

相关推荐
未知鱼2 小时前
Python安全开发之子域名扫描器(含详细注释)
网络·python·安全·web安全·网络安全
寂柒2 小时前
序列化与反序列化
linux·网络
志栋智能2 小时前
超自动化巡检:应对复杂IT环境的必然选择
运维·网络·安全·web安全·自动化
肠胃炎3 小时前
挂载方式部署项目
服务器·前端·nginx
mldlds3 小时前
windows手动配置IP地址与DNS服务器以及netsh端口转发
服务器·windows·tcp/ip
上海云盾-小余3 小时前
云主机安全加固:从系统、网络到应用的零信任配置
网络·安全·php
一直都在5724 小时前
深入理解 synchronized:到底锁的是谁?
运维·服务器
RisunJan4 小时前
Linux命令-mkbootdisk(可建立目前系统的启动盘)
linux·运维·服务器
QCzblack4 小时前
见面考复现
网络