You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

accept()与bind()、connect()的区别及accept参数特性解析

区别:accept() vs bind()/connect()

咱们先从这几个socket函数的核心定位和参数特性来拆解区别,再结合你给出的代码和手册说明细说:

1. 各自的核心用途

  • bind():纯服务器端操作,用来给监听socket绑定固定的IP地址和端口号,让客户端能精准找到这个服务。你得主动指定要绑定的地址结构体,内核只需要按照你给的地址完成绑定就行,不需要返回任何地址相关的修改信息。
  • connect():客户端专属操作,用来主动发起和服务器的连接请求。你需要提前填好服务器的IP和端口地址,内核按照你指定的地址去发起连接,同样不需要返回地址大小的修改值。
  • accept():服务器端操作,在已经调用listen()的监听socket上,等待并接收客户端的连接请求。它的关键作用不仅是建立新的连接(返回新的socket描述符peer_fd),还要返回发起连接的客户端的地址信息——这也是它参数特殊的原因。

2. 参数特性的核心差异:值-结果参数

只有accept()的addrlen参数是值-结果参数,bind()和connect()的地址长度参数只是普通的输入参数,咱们结合你给出的代码和accept(2)手册说明解析:

先看这段接收连接的代码:

struct sockaddr_in peer_addr;
socklen_t peer_addr_size = sizeof (struct sockaddr);
int peer_fd = accept(fd, (struct sockaddr *) &peer_addr, &peer_addr_size);

按照手册的说明:

addrlen参数是值-结果参数:调用者必须将其初始化为addr指向的结构体的字节大小;返回时它将包含对等方地址的实际大小。而bind和connect则不会……

具体来说:

  • 调用accept()前,我们把peer_addr_size初始化为struct sockaddr的大小,这是在告诉内核:“我给你准备了这么大的内存空间,用来存客户端的地址信息”。
  • 当accept()成功返回时,内核会把客户端地址的实际字节大小写回peer_addr_size。这是因为不同的地址类型(比如IPv4的sockaddr_in和IPv6的sockaddr_in6)大小不一样,内核需要告诉我们实际用了多少空间,方便后续处理。

而bind()和connect()不需要这个机制:

  • bind()是我们主动指定要绑定的地址,我们自己清楚这个地址结构体的大小,内核不需要返回任何修改后的大小。
  • connect()是我们主动指定要连接的服务器地址,同样我们明确知道地址结构体的大小,内核也不需要返回相关修改值。

内容的提问来源于stack exchange,提问作者Igor Liferenko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:38:28