如果有人有一分钟,我需要一点帮助。 我使用IO完成端口编写了一个Web服务器,但是在发送大文件时遇到了一些麻烦。网页似乎加载正常,但在大型文件传输过程中,WSASend()在几分钟后失败并显示错误“指定的网络名称不再可用。”
现在,当任何重叠操作失败时,我的服务器只会关闭关联的连接。这是正确的做法吗?或者我应该在关闭套接字之前重试几次失败的重叠操作?我正在使用tcp / stream套接字。
(已修复)我也收到了来自WSARecv的随机0字节数据包。我不知道该怎么做,或者问题是否相关。(/ fixed)
感谢您的帮助
编辑:现在服务器正确处理连接,并且具有更全面的日志,看起来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字节,并且只在第一个块完成时才发送下一个块。
再次感谢你提出任何想法。
P.S。我甚至只是实现了一个重试功能,以便在放弃之前重试失败的重叠IO操作五次....仍然没有运气=(
答案 0 :(得分:4)
从recv
返回的零长度数据包表示另一端的客户端已关闭连接
这解释了您后续send
客户端失败的原因。
http://www.opengroup.org/onlinepubs/009695399/functions/recv.html
如果没有可用的消息 收到了,同行已经表演了 有序关机,recv()应该返回 0
答案 1 :(得分:2)
您是否正在采取任何措施对数据传输实施某种形式的流量控制?
如果没有,那么您可能正在耗尽导致发送失败的资源。
例如,如果您只是一个接一个地发出大量WSASend()
个调用,而不是根据它们何时完成调整它们,那么每个调用将使用系统资源(非页面缓冲池和/或锁定页面,走向'锁定页数限制')。然后,您最终可能会因ENOBUFS
或类似错误而失败。
您需要做的是构建一个流量控制系统,该系统使用发送完成功能,这样您一次只能获得已知数量的未完成发送。
有关详细信息,请参阅以下问题:
Implement a good performing "to-send" queue with TCP
Limiting TCP sends with a "to-be-sent" queue and other design issues
答案 2 :(得分:0)
终于明白了。
来自Rogers Internet服务条款:
那是多么蹩脚? O_O不受限制,您不得使用(或允许其他任何人使用)我们的服务:
(xvi)运行与服务相关的服务器,包括但不限于>邮件,新闻,文件,gopher,telnet,聊天,Web或主机配置服务器,多媒体>流媒体或多用户交互论坛;
好消息:服务器工作正常=)
编辑 - 称为罗杰斯。他们证实他们正在切断我,并告诉我,我需要一个企业帐户才能运行网络服务器。