2

如果有人有时间,我需要一点帮助。我已经使用 IO 完成端口编写了一个 Web 服务器,但是在发送大文件时遇到了一些问题。网页似乎可以正常加载,但在大文件传输期间,WSASend() 会在几分钟后失败,并出现错误“指定的网络名称不再可用”。

现在,当任何重叠操作失败时,我的服务器只会关闭关联的连接。这是正确的做法吗?或者我应该在关闭套接字之前重试失败的重叠操作几次?我正在使用 tcp/stream 套接字。

(已修复)我还收到了来自 WSARecv 的随机 0 字节数据包。我不知道该怎么做,或者问题是否相关。(/已修复)

谢谢你的帮助

编辑:现在服务器正确处理连接,并且有一个更全面的日志,看起来 Len 是对的。客户端出于某种原因正在关闭连接。

日志:

Initializing Windows Sockets...
Forwarding port 80...
Starting server...
Waiting for incoming connections...
Socket 1128: Client connected.
Socket 1128: Request received
Socket 1128: Sent response
Socket 1128: Error 64: SendChunk() failed. //WSASend()
Socket 1128: Closing connection - GetQueueCompletionStatus == FALSE

所以现在的问题是,为什么客户端会关闭连接?它需要 2-5 分钟才能发生。我已将每次发送的缓冲区大小减少到 4098 字节,并且仅在第一个块完成时才发送下一个块。

再次感谢您对此的任何想法。

ps 我什至刚刚实现了一个重试功能,这样它就会在放弃之前重试失败的重叠 IO 操作五次......仍然没有运气=(

4

3 回答 3

4

从返回的零长度数据包recv表明另一端的客户端已关闭连接。
这回答了为什么您的客户后续send失败。

http://www.opengroup.org/onlinepubs/009695399/functions/recv.html

如果没有消息可以接收并且对等方已经执行了有序关闭,recv() 将返回 0。

于 2010-09-18T03:56:12.010 回答
2

您是否正在做任何事情来对您的数据传输施加某种形式的流量控制?

如果不是,那么您可能正在使用导致发送失败的资源。

例如,如果您只是WSASend()一个接一个地发出大量调用,而不是根据它们完成的时间来调整它们,那么每个调用都将使用系统资源(非分页池和/或锁定页面,这些资源会达到“锁定页面限制” )。然后,您最终可能会因ENOBUFS错误或类似错误而失败。

您需要做的是构建一个流程控制系统,该系统在发送完成后工作,以便您一次只有已知数量的未完成发送。

有关更多详细信息,请参阅这些问题:

使用 TCP 实现性能良好的“发送”队列

使用“待发送”队列和其他设计问题限制 TCP 发送

于 2010-09-18T06:59:29.760 回答
0

终于想通了。

来自罗杰斯互联网服务条款:

不受限制,您不得使用(或允许其他任何人使用)我们的服务来:

(xvi) 操作与服务相关的服务器,包括但不限于>邮件、新闻、文件、gopher、telnet、聊天、Web 或主机配置服务器、多媒体>流媒体或多用户交互式论坛;

那有多蹩脚?o_o

好消息:服务器工作正常 =)

编辑-称为罗杰斯。他们证实他们正在切断我的联系,并告诉我我需要一个企业帐户来运行 Web 服务器。

于 2010-09-20T23:24:59.060 回答