Unix中的TCP套接字 - 通知服务器我已完成发送

时间:2011-06-22 18:07:14

标签: sockets unix tcp

我有一个小小的TCP应用程序,其中许多客户端连接到服务器,向其发送数据(通过write() - 它们也发送消息大小)然后退出。我有客户端在完成发送时将\ 0 \ 0发送到服务器 - 我这样做,如果服务器从read()获得零,那么它知道客户端出现了问题(如SIGKILL)。我的问题是 - 是否有任何编程方式(一些系统调用)通知服务器我已完成发送 - 而不是服务器检查始终为\ 0 \ 0?服务器在客户端/侦听套接字上使用poll()来检测是否有要读取的内容/新的连接请求,顺便说一句。

我应该发送信号吗?但是,我怎么知道哪个描述符停止轮询呢?

我看了this,但那里的答案或多或少都是我现在使用的

2 个答案:

答案 0 :(得分:4)

如果您的协议比单个请求/响应模型复杂一点,那么在应用程序级别(例如,使用\0\0)执行此操作是正确的方法。

例如,HTTP 1.0在单个请求/响应之后直接关闭连接:客户端发送其请求命令,服务器回复其响应并关闭连接。

在您进行更复杂交换的协议中,有一些特定命令用于指示消息的结束。例如,SMTP和POP3以行分隔。通过SMTP发送电子邮件内容时,您在一行中使用.指示邮件结束(实际邮件中的.将转义为..)。您还可以获得QUIT等命令来表明您已完成。

在HTTP 1.1中,请求标头集由空行终止(例如GET / HTTP/1.1 +行上的每个标头+空行),因此服务器知道请求结束的位置。 HTTP 1.1中的响应然后使用Content-Length标头(用于在响应主体结束时发出信号)或使用chunked transfer encoding基本上插入多个分隔符以指示是否有更多数据即将到来(通常,当服务器事先不知道数据大小时使用它)。 (具有正文的请求也使用相同的标头来指示请求何时结束。)

服务器很难知道它何时完成读取,因为通常无法检测是否socket is disconnected(或者更确切地说,即使客户端没有发送任何数据,它仍然连接)。通过在应用程序级别发送一些分隔符或长度指示符,可以避免此类问题(或者可以检测何时出现问题/超时)。

答案 1 :(得分:2)

这是在应用程序级别完成的。在HTTP中,它通过关闭套接字来完成响应。在服务器收到两次返回后,在HTTP中也知道GET请求已经完成发送,如果有内容长度的头,它知道客户端/服务器在X字节后完成发送。

你需要实现类似的东西。