簡體   English   中英

C# 客戶端服務器 TCP 客戶端監聽

[英]C# Client Server TCP Client Listening

我有一段時間在編寫 3D 代碼,現在,我不想創建一個與網絡配合使用的游戲。 我使用 System.Net 和 System.Net.Sockets。

我的服務器愚蠢得要命,它只能保持一個連接(稍后,我會將其更改為多連接能力)。 它有一個 TcpListener 偵聽端口 10000 上的 127.0.0.1。(只是為了測試)。 在那里,我有一個 DO While 循環,它檢查接收到的數據並顯示它。

我的客戶端是一個 TcpClient。 它連接到服務器並發送消息。 這里沒什么特別的,它是通過 TcpClient.GetStream().Write() 完成的。 這很好用。 我還可以在發送后立即閱讀一個答案。

但是如果服務器會在沒有客戶端詢問的情況下發送一些信息呢? 例如:服務器上的所有玩家都會收到一個物品。 我必須如何設置我的客戶端才能接收此類消息?

我的客戶必須循環詢問嗎? 還是我必須以某種方式委托? 我可以創建一個循環,每 200 毫秒或其他時間詢問此類信息,但這將如何改變 3D 游戲的性能?

這是如何在專業游戲開發中完成的?

使用 TcpClient 和 TcpListener 類的異步功能。
在您的客戶端:

private TcpClient server = new TcpClient();

async Task Listen()
{
    try {
        IPAddress IP = IPAddress.Loopback // this is your localhost IP
        await server.ConnectAsync(IP,10000); // IP, port number

        if(server.Connected) {
           NetworkStream stream = server.GetStream();

           while (server.Connected) {
               byte[ ] buffer = new byte[server.ReceiveBufferSize];
               int read = await stream.ReadAsync(buffer, 0, buffer.Length);
               if (read > 0 ){
                    // you have received a message, do something with it
               }
           }
        }
    }
    catch (Exception ex) {
         // display the error message or whatever
         server.Close();
    }
}

使用異步客戶端套接字:

“客戶端使用異步套接字構建,因此在服務器返回響應時不會暫停客戶端應用程序的執行。”

http://msdn.microsoft.com/en-us/library/bew39x2a(v=vs.110).aspx

private static void ReceiveCallback( IAsyncResult ar ) {
        try {
            // Retrieve the state object and the client socket 
            // from the asynchronous state object.
            StateObject state = (StateObject) ar.AsyncState;
            Socket client = state.workSocket;

            // Read data from the remote device.
            int bytesRead = client.EndReceive(ar);

            if (bytesRead > 0) {
                // There might be more data, so store the data received so far.
            state.sb.Append(Encoding.ASCII.GetString(state.buffer,0,bytesRead));

                // Get the rest of the data.
                client.BeginReceive(state.buffer,0,StateObject.BufferSize,0,
                    new AsyncCallback(ReceiveCallback), state);
            } else {
                // All the data has arrived; put it in response.
                if (state.sb.Length > 1) {
                    response = state.sb.ToString();
                }
                // Signal that all bytes have been received.
                receiveDone.Set();
            }
        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
    }

在此 ReceiveCallback 中,您可以創建一個處理服務器消息的開關。

例如:消息的第一個字節是命令,命令之后是正確的數據。 在 switch 中,您可以處理該命令並執行一些代碼。

暫無
暫無

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

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