我有一个小小的TCP应用程序,其中许多客户端连接到服务器,向其发送数据(通过write() - 它们也发送消息大小)然后退出。我有客户端在完成发送时将\ 0 \ 0发送到服务器 - 我这样做,如果服务器从read()获得零,那么它知道客户端出现了问题(如SIGKILL)。我的问题是 - 是否有任何编程方式(一些系统调用)通知服务器我已完成发送 - 而不是服务器检查始终为\ 0 \ 0?服务器在客户端/侦听套接字上使用poll()来检测是否有要读取的内容/新的连接请求,顺便说一句。
我应该发送信号吗?但是,我怎么知道哪个描述符停止轮询呢?
我看了this,但那里的答案或多或少都是我现在使用的
答案 0 :(得分:4)
如果您的协议比单个请求/响应模型复杂一点,那么在应用程序级别(例如,使用\0\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字节后完成发送。
你需要实现类似的东西。