socket:客户端在收到最后一个字节后等待

时间:2009-04-23 12:07:37

标签: c networking client-server posix

我在C中有客户端/服务器程序,我通过它从服务器将文件传输到客户端。

但是,即使在收到文件的最后一个字节后,客户端也在等待recv。客户端只有在我杀了它或服务器被我杀死时才会终止。但服务器必须处于循环中,因为它必须接受其他客户的请求。

我在服务器中使用fork()来接受每个客户端的请求。我在客户端的请求被接受后退出子进程,但客户端只在整个服务器程序被终止时终止。

为什么客户端在服务器的子进程退出时终止?

您可以查看服务器代码here和客户端代码here

4 个答案:

答案 0 :(得分:3)

在发送完所有数据后,您应该确保在服务器进程中调用shutdown(s, SHUT_WR)后跟close(s)

shutdown()的调用告诉TCP层没有更多数据要发送。

TBH,我不太清楚为什么单独调用close()也不能实现这一点。

编辑 - 我现在已经想到了 - 这是因为在你的代码中,父进程仍然打开了套接字,因此它不会被内核拆除。如果在fork()后添加一些额外的逻辑:

if (p > 0) {
    close(connected);
}

然后您的代码无法调用shutdown()

如果您使用我在my answer发送的代码来自昨天的问题,那么客户端将获得bytes_received计数为零,然后终止其循环。

答案 1 :(得分:0)

你应该打电话给: 关机(s,SD_SEND); 字关闭(多个);

发送文件以关闭套接字后,在服务器上

答案 2 :(得分:0)

这有点难,更多细节会很好。你在使用TCP / IP吗?既然你谈到文件传输,我会假设它是TCP。

如果您在服务器端终止拥有连接到客户端的套接字的进程,则应该导致连接终止。然后客户端的recv()调用应该完成并返回-1(或0,而不是100%肯定)。如果做不到这一点,请考虑在主服务器进程中明确关闭套接字(不确定如何设置套接字所有权)。

答案 3 :(得分:-1)

有两种方法可以读取插座......

  1. 使用recv()逐字节接收,但问题是如果您的内容在数据中间包含-1,那么它将指示文件结束。

  2. 另一种方法是从流中读取缓冲区,此方法将返回从流中读取的字节数,如果返回0表示它的流结束。