TCP套接字读取总是阻塞
我有一个客户端 TCP 套接字,每五秒写入几个字节,服务器立即回显这些字节。
Connect() 和 write() 工作得很好,并且我在 IP 层有一个回调,通知我服务器的回显。这在发送之间可靠地发生。
但我无法从套接字读取回声。
我尝试使用select()来通知我传入的回声。奇怪的是,直到我关闭套接字才调用我的回调,此时它被连续调用。然而,对于每个调用,read() 都返回 -1/WOULD_BLOCK。
当 IP 层通知我传入数据时,我的第二种方法会异步调用 read()。同样,read() 仅返回 -1/WOULD_BLOCK。我意识到 read() 可以将数据传输到套接字层,但希望这意味着在下一次写入后可以读取更多内容。
我倾向于认为我在某种程度上滥用了 API,因为我是一个 IP/套接字菜鸟,而且 select 方法的行为非常奇怪。
这不太可能是一个愚蠢的错误,因为几乎相同的代码路径非常适合 UDP 模式。唯一的区别:对于 UDP,我使用 DATAGRAM 模式、sendto() 和 recvfrom()。对于 TCP,我使用 STREAM 模式、write() 和 read()。
I have a client TCP socket that writes a few bytes every five seconds, the server echoes the bytes right back.
Connect() and write() work just fine, and I have a callback at the IP layer that notifies me of the server's echo. This reliably happens between sends.
But I'm having trouble reading the echo from the socket.
I tried using select() to notify me of the incoming echo. Strangely, my callback wasn't invoked until I closed the socket, at which point it was called continuously. For each of these calls, however, read() returned -1/WOULD_BLOCK.
My second approach calls read() asynchronously when the IP layer notifies me of the incoming data. Similarly, read() only returns -1/WOULD_BLOCK. I realize the read() could beat the data to the socket layer, but hopefully it would just mean more to read after the next write.
I'm inclined to think I'm somehow misusing the API since I'm an IP/sockets noob and the select approach behaved so strangely.
It's unlikely a dumb bug since the nearly identical code path works perfectly for UDP mode. The only differences: for UDP I use DATAGRAM mode, sendto(), and recvfrom(). For TCP I use STREAM mode, write(), and read().
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来服务器处于 TCP 回显应用程序崩溃的状态,但 UDP 回显正常并且 TCP 层仍然能够处理流量。
因此,我的应用程序会从传入 TCP 的 IP 收到通知,并相信有要读取的回显,但在套接字层找不到数据。我预计这意味着我使用 API 或 IP 和套接字之间的层出现问题。不,通知是针对服务器 ACK 而不是回显,并且由于这是在 TCP 层处理的,因此它从未到达套接字。
It appears the server was in a state where the TCP echo application had crashed, but UDP echo was fine and the TCP layer was still capable of handling traffic.
So my app would get notification from IP of incoming TCP and believe there was an echo to be read, but find no data at the socket layer. I expected this meant a problem with my use of the API or the layers between IP and sockets. Nope, the notification was for the server ACK rather than the echo, and since that is handled at the TCP layer, it never made it to the socket.