写入数据后向套接字发送错误响应

时间:2016-06-06 06:26:50

标签: c sockets

我有一个使用c编写HTTP服务器的任务。服务器读取请求并相应地发送响应。当请求是文件的路径时,我需要读取文件内容并将其作为响应发送给客户端。

文件大小没有限制,所以我按块读取它并按块发送响应。老师说如果在已经写完部分响应后recv / send调用失败,则可以关闭连接并继续,但应通知客户端响应未正确发送。

我的问题是,假设发送呼叫失败,尝试发送响应未正确发送的消息可能会再次失败。如何通知客户端发送响应时出错?

3 个答案:

答案 0 :(得分:2)

您的老师并未说您的服务器应该通知客户端,但是recv()已经(已经)通知客户端,因此,除了关闭之外,您在服务器端没有什么特别需要做的连接。

1 也就是说,假设你的老师没有困惑。

答案 1 :(得分:1)

你老师的陈述没有说明意义,或含糊不清。 HTTP状态代码位于有效负载之前。如果写入有效负载时出错,则除了重置连接之外没有办法通知对等方,如果您知道如何执行此操作,或者由于发送错误(最可能)已经发生这种情况。

答案 2 :(得分:0)

  

老师说如果在已经写完部分响应后recv / send调用失败,则可以关闭连接并继续,但应通知客户端响应未正确发送。

首先,在您开始recv()回复之前,您不应该致电send(),直到回复完整发送为止。在当前响应完成之前,您无法启动recv()下一个请求。

其次,如果recv()send()因任何原因失败,您必须关闭当前连接,没有其他选择。

  

我的问题是,假设发送呼叫失败,尝试发送响应未正确发送的消息可能会再次失败。如何通知客户端发送响应时出错?

你不能,也不应该尝试。如果这是你的老师告诉你的事情,那么要么你误解了老师的实际说法,要么你的老师不理解HTTP的实际工作方式。

发生连接失败时,关闭连接是唯一的选择。如果客户端尚未失败,它将(最终)检测到关闭(或超时),并且由于未完全收到响应这一事实将知道响应失败。它如何检测响应的结束取决于响应的格式(详见RFC 2616 Section 4.4 Message Length)。

请注意 - 有一种情况是连接关闭并不表示响应失败!如果是服务器:

  1. 未回复HEAD请求;

  2. 未使用1xx204304回复代码回复;

  3. 未发送Content-LengthTransfer-Encoding: identity响应标头;

  4. 不以multipart/byteranges格式发送回复正文;

  5. 然后,服务器正常关闭连接 完成响应(服务器使用shutdown(SD_SEND)shutdown(SD_BOTH)故意关闭,后者发送带有{的{ {1}}已启用标记。在某些平台上,包括Windows,FIN / close()将执行隐式关闭,但最好是明确的。)

    客户端必须查看响应标头以检测响应的发送方式并采取相应措施。如果它属于最后一个条件,则仅将正常断开连接视为成功。任何其他类型的断开都将被视为失败。因此,服务器应始终至少发送closesocket()Content-Length标头。它避免了断开连接代表的模糊性。