【问题标题】:Linux, C: IPv6 socket: write blocksLinux,C:IPv6 套接字:写入块
【发布时间】:2015-11-29 22:02:54
【问题描述】:

我有服务器和客户端应用程序,在 Ubuntu1410 默认内核上以 IPv6 运行。

服务:socket 监听本地 TCP 端口并使用 select() 处理新的连接和数据;

客户端:socket通过TCP连接服务器的IPv6地址和端口。

可以成功建立连接。 但是,当 write() 数据时,缓冲区大小为 128K,它将阻塞在write()

因为我需要写很多数据,所以我有一个 for 循环来调用 write()。有时,write() 会成功一两次,然后再次阻塞。

我的应用支持 IPv4 和 IPv6。 write() 适用于 IPv4。

而且,如果我在 ::1 上进行测试(服务器和客户端在同一台机器上运行),IPv6 也可以工作。

r = write(fd, buf, buf_size);

【问题讨论】:

  • 使用wireshark查看发生了什么。 ipv6 和 v4 的工作方式非常不同,以至于客户端和服务器之间可能存在网络问题。
  • 请注意,IPv6 标头大于 IPv4 标头,因此同一 MTU 上的用户数据分段将有所不同。
  • wireshark 告诉我:在客户端发送一些数据包并被服务器接收后,服务器也发送了 ACK;然后服务器暂时不会向客户端响应 ACK。 (在此期间,客户端也向服务器发送 PUSH)。过了一会儿,它再次向客户端回复 ACK,看起来客户端停止了任何操作......
  • 目前尚不清楚哪一方在发送。请澄清。
  • 在我看来,这是按预期工作的。当客户端读取缓慢并且缓冲区填满时,对write() 的调用绝对应该阻塞。在我看来,您没有正确测试这是否正在发生。

标签: c linux sockets tcp ipv6


【解决方案1】:

Linux 文件描述符可以设置为非阻塞模式。它可以在创建时完成(open 系统调用或socket 系统调用),也可以在事后通过fctl 系统调用完成。有关详细信息,请参阅手册页(第 2 节)。

如果文件描述符设置为非阻塞模式,则对其进行的否则会阻塞的操作将返回 -1 并将 errno 设置为 EAGAIN (==EWOULDBLOCK)。

【讨论】:

  • 在服务器和cient sdes上,我在socket(,,)中添加了SOCK_NONBLOCK。但客户端套接字 connect() 回复错误代码 115,“Operation now in progress”。
【解决方案2】:

如果 TCP 发送阻塞,则接收方读取缓慢。

【讨论】:

    猜你喜欢
    • 2013-11-14
    • 2012-05-18
    • 2013-05-25
    • 2013-11-25
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多