0
我在C#中創建套接字服務器,並在PHP中創建客戶端。客戶端和服務器之間的會話是這樣的:C#套接字問題
- 客戶端連接
- 服務器發送歡迎消息
- 客戶端發送數據
- 服務器發送響應
- (重複步驟3 - 4,直到客戶端斷開連接)
它一直工作到第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);
這解釋了很多!我將如何實現一個方法,從套接字讀取,直到達到某個特定的分隔符(讓它成爲換行符或其他內容)? – Max 2009-11-24 12:12:16
@Max:這不是特別容易,因爲你可能會得到比你想消費更多的數據,所以你必須在某個地方存儲。不過,只要將套接字的流封裝在StreamReader中並持續調用Read,然後查看緩衝區以查看您感興趣的字符是否存在。當你有一個多字符分隔符當然是更復雜... – 2009-11-24 12:15:51
非常感謝Jon的解釋。這澄清了我的套接字服務器和客戶端的一些奇怪的行爲。 – Max 2009-11-24 13:18:28