Unix 中的 TCP 套接字 - 通知服务器我已完成发送 [英] TCP socket in Unix - notify server I am done sending

查看:24
本文介绍了Unix 中的 TCP 套接字 - 通知服务器我已完成发送的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a tiny little TCP app where many clients connect to a server, send data to it (via write() - they are also sending message size) and then exit. I have the clients send \0\0 to the server when done sending - and I make it so that if the server gets a zero from read() then it knows something went wrong in the client (like SIGKILL). My question is - is there any programmatic way (some sys call) to notify the server that I am done sending - instead of the server checking always for \0\0 ? Server uses poll() on clients/listening socket to detect if there is something to read/new connection request, btw.

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

Should I send a signal ? But how do I know which descriptor to stop polling then ?

我阅读了这个 但答案或多或少是我现在使用的

I read this but the answers there are more or less what I use now

推荐答案

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

Doing it at the application level (e.g. using \0\0 as you're doing it) is the correct way to do if your protocol is a bit more complex that a single request/response model.

例如,HTTP 1.0 在单个请求/响应后立即关闭连接:客户端发送其请求命令,服务器响应其响应并关闭连接.

HTTP 1.0, for example, closes the connection straight after a single request/response: the client sends its request command, the server replies with its response and closes the connection.

在具有更复杂交换的协议中,有特定的命令来指示消息的结束.例如,SMTP 和 POP3 是以行分隔的.当通过 SMTP 发送电子邮件的内容时,您在一行中使用 . 指示消息的结尾(实际消息中的 . 被转义为 .>...).您还会收到诸如 QUIT 之类的命令来表示您已完成.

In protocols where you have a more complex exchange, there are specific commands to indicate the end of a message. SMTP and POP3, for example, are line-delimited. When sending the content of an e-mail via SMTP, you indicate the end of the message using . on a single line (. in the actual message is escaped as ..). You also get commands such as QUIT to indicate you're done.

在 HTTP 1.1 中,请求标头集以空行终止(例如 GET/HTTP/1.1 + 一行上的每个标头 + 空行),因此服务器知道在哪里请求的结尾是.HTTP 1.1 中的响应然后使用 Content-Length 标头(在响应正文结束时发出信号)或使用 chunked transfer encoding 本质上插入了许多分隔符来指示是否有更多数据到来(通常,当服务器不知道数据大小时使用它提前).(具有正文的请求也使用相同的标头来指示请求何时结束.)

In HTTP 1.1, the set of request headers is terminated by an empty-line (e.g. GET / HTTP/1.1 + each header on a line + an empty line), so the server knows where the end of the request is. The responses in HTTP 1.1 then use either a Content-Length header (to signal when the end of the response body is going to be) or use chunked transfer encoding which essentially inserts a number of delimiters to indicated whether there's more data coming (usually, it's used when the data size isn't known by the server in advance). (Requests that have a body also use the same headers to indicate when the request ends.)

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

It's otherwise difficult for the server to know when it's done reading, since it's generally not possible to detect whether a socket is disconnected (or rather, if it's still connected even though the client isn't sending any data). By sending some delimiter or length indicator at the application-level, you avoid this sort of problem (or can detect when there's a problem/timeout).

这篇关于Unix 中的 TCP 套接字 - 通知服务器我已完成发送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆