我们使用以下代码接受传入的HTTP请求。
var localEndPoint = new IPEndPoint(IPAddress.Any, Port);
var serverSocket = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
serverSocket.Bind(localEndPoint);
serverSocket.Listen(backlog: 25);
while (true)
{
using (var clientSocket = serverSocket.Accept())
{
if (clientSocket.Available > 0)
{
var builder = new StringBuilder();
while (clientSocket.Available > 0)
{
var currentBytes = new byte[clientSocket.Available];
var bytesReceived = clientSocket.Receive(currentBytes);
var currentBytesString =
new string(Encoding.UTF8.GetChars(currentBytes));
builder.Append(currentBytesString);
}
}
}
}
即使连接有数据,有时clientSocket.Available
也为零。我们实现的解决方案是在接受连接之后等待,然后再检查数据是否可用。我们这样做:
var start = DateTime.Now;
var duration = new TimeSpan(0);
while (clientSocket.Available <= 0 || duration.Milliseconds < 1000)
{
duration = DateTime.Now - start;
Thread.Sleep(100);
}
接受连接后,我们需要等待多长时间才能在套接字中提供连接数据?
感谢szym为这种方法提供灵感。它现在正在运作。
while (true)
{
using (var clientSocket = serverSocket.Accept())
{
var builder = new StringBuilder();
do
{
var currentBytes = new byte[50];
var bytesReceived = clientSocket.Receive(currentBytes);
var currentBytesString =
new string(Encoding.UTF8.GetChars(currentBytes));
builder.Append(currentBytesString);
}
while (clientSocket.Available > 0);
}
}
答案 0 :(得分:1)
通常,您可能需要等待一段时间(想想具有巨大往返时间的糟糕网络),某些平台上的默认超时为20秒!
但是,在困循环中检查Available
的方法是轮询,这是浪费CPU。您应该阻止等待数据到达的Receive
(如果您需要处理多个连接,可能会生成一个线程),或者使用非阻塞方法。
引用documentation(强调我的):
如果您使用非阻止套接字,则可以使用“可用” 在调用Receive之前确定数据是否排队等待读取。 可用数据是网络中排队的数据总量 阅读缓冲区。如果网络缓冲区中没有数据排队, 可用返回0。