簡體   English   中英

C#套接字問題

[英]C# socket problem

我在C#中創建套接字服務器,在PHP中創建客戶端。 客戶端和服務器之間的對話是這樣的:

  1. 客戶端連接
  2. 服務器發送歡迎消息
  3. 客戶發送數據
  4. 服務器發送響應
  5. (重復步驟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);

你從套接字讀取,直到所有的數據已被讀取-這意味着“所有的數據,直到關閉套接字”。 您的PHP客戶端正在寫入數據,但沒有關閉套接字-因此服務器一直在等待。

TCP套接字提供數據 沒有“當前消息的結尾”的概念,這就是您想要的樣子。

處理此問題的三種方法通常是:

  • 消息定界符(例如,換行符)
  • 消息長度前綴(消息本身之前的消息中的字節數)
  • 對每個請求/響應對使用不同的連接

可能會使用帶有超時的讀取,並假設如果在最近5秒鍾內沒有看到更多數據,那么您已經獲得了完整的消息-但這是脆弱,低效的,通常是一個壞主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM