socket通信中的accept函数

int connfd = ::accept(m_sockfd, (struct sockaddr*)&addr, &addr_len);

你已经意识到这里有的是传入参数,有的是传出参数,说明你在认真理解系统调用的行为 —— 这是系统编程非常重要的能力。


✅ 先回顾一下 accept() 的函数原型:

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

✅ 参数逐个讲清楚:

参数名类型方向说明
sockfdint输入参数监听 socket 的文件描述符,即 m_sockfd,必须已 listen()
addrstruct sockaddr*输出参数用于返回客户端的地址信息(写入数据)
addrlensocklen_t*输入/输出参数初始传入 addr 的大小,返回时被修改为实际使用的大小

✅ 一句话总结每个参数作用

m_sockfd(传入参数)

  • 这是你前面用 socket() + bind() + listen() 得到的监听 socket。

  • 告诉操作系统:“我现在要从这个 socket 上接收一个连接请求”。


(struct sockaddr*)&addr(传出参数)

  • 这是输出用的结构体,系统会在连接建立后,把客户端的 IP/端口信息写入到 addr 里。

  • 所以你需要提前定义这个变量(如 sockaddr_in addr;),传指针进去。


&addr_len(传入 + 传出)

  • 你一开始要告诉操作系统:“这个地址结构的大小是多大”(通常是 sizeof(addr))。

  • 系统会在调用结束时修改它的值为实际写入的字节数(即客户端地址信息长度)。

  • 这是典型的 C 接口“in/out”双向参数。


✅ 图示理解参数传递方向:

调用前:
  m_sockfd → 已监听的 socket
  addr     → 空结构体,等着系统写入客户端地址
  addrlen  → sizeof(addr)

调用后(成功):
  connfd   → 新的连接 socket
  addr     → 填好了客户端 IP/端口
  addrlen  → 系统写回实际地址长度

✅ 常见错误提醒:

  1. ❌ 没有给 addr_len 设置初值:

    socklen_t addr_len;
    accept(sockfd, (sockaddr*)&addr, &addr_len); // ❌ 未初始化,可能失败
    
  2. ✅ 正确做法是:

    socklen_t addr_len = sizeof(addr);
    

✅ 补充:返回值 connfd

  • 它是新的 socket fd,专门用于与当前这个客户端通信

  • m_sockfd 不同(后者还在继续监听新的连接)


✅ 总结重点:

参数输入 / 输出作用
m_sockfd输入哪个监听 socket 来 accept
addr输出客户端地址将被写到这里
addr_len输入 + 输出告诉系统结构体多大、系统写入实际使用大小

accept函数是在socket编程中用于接受客户端连接的函数。当服务器端创建了一个监听socket后,可以调用accept函数来等待客户端的连接请求。 accept函数的原型为: ```c int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); ``` 其中,sockfd是服务器端创建的监听socket的文件描述符;addr是指向struct sockaddr类型的指针,用于存储客户端的IP地址和端口号;addrlen是一个指向socklen_t类型的指针,用于存储客户端地址结构体的长度。 accept函数的工作流程如下: 1. 服务器调用listen函数socket设置为监听状态,等待客户端连接。 2. 当有客户端发起连接请求时,服务器调用accept函数进行处理。 3. accept函数会阻塞等待,直到有客户端连接请求到达。 4. 当有连接请求到达时,accept函数会创建一个新的socket,并返回该新socket的文件描述符。 5. 这个新的socket会与客户端建立连接,服务器端可以通过该socket与客户端进行通信。 6. 同时,accept函数会将客户端的IP地址和端口号存储在addr参数所指向的结构体中,并将结构体的长度存储在addrlen参数中。 需要注意的是,accept函数在没有新的连接请求到达时会一直阻塞等待,直到有新的连接请求才会返回。如果需要非阻塞地等待连接请求,可以通过设置socket为非阻塞模式或者使用select函数来实现。另外,accept函数一般会在一个循环中使用,以便持续接受客户端的连接请求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值