我在C#中创建一个套接字服务器,在PHP中创建一个客户端。客户端和服务器之间的对话是这样的:
直到第3步。客户端的数据由服务器接收。但是,客户端会一直等待,直到服务器发送响应并最终超时。
以下是相关的C#代码:
class Program
{
private const int CONNECT_QUEUE_LENGTH = 4;
static void ListenForRequests()
{
Socket listenSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSock.Bind(new IPEndPoint(IPAddress.Any, 9999));
listenSock.Listen(CONNECT_QUEUE_LENGTH);
listenSock.Blocking = true;
byte[] data = new byte[1024];
while (true)
{
Socket newConnection = listenSock.Accept();
newConnection.Blocking = true;
// Create new thread for each request
var t = new Thread(() => new RequestHandler(newConnection));
t.Start();
}
}
}
class RequestHandler
{
public RequestHandler(Socket socket)
{
Util.WriteToSocket("A message", socket);
Console.WriteLine("Received: " + Util.ReadSocketToEnd(socket).Length);
Util.WriteToSocket("Fin!", socket);
}
}
static class Util
{
public static string ReadSocketToEnd(Socket newConnection)
{
var sb = new StringBuilder();
byte[] data = new byte[1024];
int receivedDataLength = newConnection.Receive(data);
while (receivedDataLength > 0)
{
try
{
sb.Append(Encoding.UTF8.GetString(data, 0, receivedDataLength));
receivedDataLength = newConnection.Receive(data);
}
catch (SocketException)
{
break;
}
}
return sb.ToString();
}
public static void WriteToSocket(string message, Socket client)
{
byte[] data = Encoding.UTF8.GetBytes(message);
client.Send(data, SocketFlags.None);
}
}
这是简单的PHP客户端,没有任何错误处理等:
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$result = socket_connect($socket, '127.0.0.1', 9999);
print 'receiving: ' . chr(10);
print socket_read ($socket, 10) . chr(10);
print 'receive end' . chr(10);
$message = str_repeat("Message to sent", 1000);
socket_write($socket, $message, strlen($message));
print 'message sent' . chr(10);
print 'reading fin' . chr(10); // This is printed, but a response is never received
print socket_read ($socket, 10) . chr(10);
print 'fin read!' . chr(10);
socket_shutdown($socket);
答案 0 :(得分:5)
您正在读取套接字,直到所有数据已被读取 - 这意味着“所有数据直到套接字关闭”。您的PHP客户端正在写入数据,但没有关闭套接字 - 所以服务器正在等待。
TCP套接字提供流数据。没有“当前消息结束”的概念,这就是你想要的。
处理此问题的三种方法通常是:
你可以潜在地使用带有超时的读取,并假设如果你在过去的5秒内没有看到任何更多的数据,你就得到了整个信息 - 但这很脆弱,效率低下,通常是个坏主意。