【问题标题】:Tcp socket read always blocksTcp 套接字读取总是阻塞
【发布时间】:2011-11-23 23:51:02
【问题描述】:

我有一个客户端 TCP 套接字,它每五秒写入几个字节,服务器立即回显这些字节。

Connect() 和 write() 工作得很好,我在 IP 层有一个回调通知我服务器的回声。这在发送之间可靠地发生。

但我无法从套接字读取回声。

我尝试使用 select() 来通知我传入的回声。奇怪的是,我的回调直到我关闭套接字才被调用,此时它被连续调用。然而,对于这些调用中的每一个,read() 返回 -1/WOULD_BLOCK。

我的第二种方法在 IP 层通知我传入数据时异步调用 read()。同样,read() 只返回 -1/WOULD_BLOCK。我意识到 read() 可以将数据传输到套接字层,但希望它只是意味着在下一次写入后读取更多内容。

我倾向于认为我在某种程度上滥用了 API,因为我是一个 IP/sockets 菜鸟,而且 select 方法的行为很奇怪。

这不太可能是一个愚蠢的错误,因为几乎相同的代码路径非常适合 UDP 模式。唯一的区别:对于 UDP,我使用 DATAGRAM 模式、sendto() 和 recvfrom()。对于 TCP,我使用 STREAM 模式、write() 和 read()。

【问题讨论】:

  • 当你调用 read() 时,你提供的 count 值是多少?
  • 请出示您的实际阅读代码。您显然使用错误的 API。我猜你在滥用SOCKET 句柄。
  • @TJD:“计数”是指字节数?我分配并要求最多 4k。相同的代码适用于 UDP recv(),当然对于 UDP 我传递了额外的 fromaddr 参数。
  • @mr_dude,是的,我就是这个意思。标准的 read() 声明命名参数计数。 ssize_t read(int fd, void *buf, size_t count);
  • @Remy:代码在离线网络上,如果我错误地使用了 api,大概我对其(错误)使用的描述就足够了。我不确定如何滥用套接字句柄,如果我传递了无效的 sockfd(零、错误的协议等),read() 会告诉我。

标签: sockets tcp udp ip berkeley-sockets


【解决方案1】:

服务器似乎处于 TCP 回显应用程序崩溃的状态,但 UDP 回显很好,并且 TCP 层仍然能够处理流量。

所以我的应用会从传入 TCP 的 IP 获得通知,并相信有一个回显要读取,但在套接字层找不到数据。我预计这意味着我使用 API 或 IP 和套接字之间的层存在问题。不,通知是针对服务器 ACK 而不是回显,并且由于这是在 TCP 层处理的,因此它从未到达套接字。

【讨论】:

  • 这没有任何意义。如果 TCP 回显已关闭,怎么会有传入的 TCP 数据?而且您不会在 ACK 上收到 select() 事件。毫无疑问,您使用的 API 错误,但没有看到代码就无法进一步评论。
  • 服务器端 TCP 层正在处理消息传递,但客户端应用程序已崩溃,因此没有数据。从 IP 层,传入的数据只是 TCP 消息传递。
  • 你也可以稍微提高你的语气。
猜你喜欢
  • 2019-02-06
  • 2012-01-05
  • 1970-01-01
  • 2011-12-27
  • 2012-07-24
  • 2016-07-15
  • 2015-01-15
  • 2011-05-31
  • 2015-08-28
相关资源
最近更新 更多