使用Unity3d NetworkTransport.Receive连接ID导致消息误发送给自己
Hey there! Let's figure out why your server is sending that "pong" message to itself instead of the client—this is a super common gotcha with Unity's low-level NetworkTransport API, so we can sort this out quickly.
The Core Issue: Mixing Up Connection IDs
9 times out of 10, this happens because you're using the wrong ID when calling NetworkTransport.Send() on the server. Here's what's going wrong and how to fix it:
1. Don't Confuse Host ID with Connection ID
When you start your server, you get a hostId from NetworkTransport.AddHost()—this is just the identifier for the server's listening socket, not the ID you use to send messages to a client.
When a client connects, the server will receive a ConnectEvent, and you need to call NetworkTransport.AcceptConnection() to get a valid connectionId for that specific client. This is the ID you must use when sending messages back.
2. Example of Wrong vs. Correct Code
Let's look at the mistake first:
// ❌ Wrong: Using the server's hostId as the connectionId byte error; byte[] pongData = Encoding.UTF8.GetBytes("pong"); NetworkTransport.Send(serverHostId, serverHostId, reliableChannel, pongData, pongData.Length, out error);
This sends the message to the server's own host socket, hence why it's receiving it itself.
Here's the corrected version, using the client's actual connection ID from the received event:
// ✅ Correct: Using the client's connectionId from the DataEvent/ConnectEvent void Update() { int recHostId; int recConnectionId; int recChannelId; byte[] recBuffer = new byte[1024]; int bufferSize = 1024; int dataSize; byte error; NetworkEventType eventType = NetworkTransport.Receive( out recHostId, out recConnectionId, out recChannelId, recBuffer, bufferSize, out dataSize, out error ); switch (eventType) { case NetworkEventType.ConnectEvent: // Accept the connection to get a valid client connection ID int acceptedConnId = NetworkTransport.AcceptConnection(recConnectionId, out error); if (error == 0) { Debug.Log($"Client connected: {acceptedConnId}"); } break; case NetworkEventType.DataEvent: string receivedMsg = Encoding.UTF8.GetString(recBuffer, 0, dataSize); if (receivedMsg == "ping") { // Send pong using the client's connectionId from the DataEvent byte[] pongData = Encoding.UTF8.GetBytes("pong"); NetworkTransport.Send( recHostId, recConnectionId, reliableChannel, pongData, pongData.Length, out error ); if (error != 0) { Debug.LogError($"Send error: {(NetworkError)error}"); } } break; } }
3. Always Validate Connection IDs
- Make sure you're storing valid client connection IDs (from
AcceptConnection()) and using those for all outgoing messages to clients. - Check the
erroroutput parameter every time you callNetworkTransport.Send()—if you getInvalidConnectionId, that means you're using an ID that doesn't correspond to an active client connection.
Quick Recap
- Use the
connectionIdfrom the receivedDataEventor the accepted connection ID fromConnectEventwhen sending replies. - Never use the server's
hostIdas a connection ID for sending messages. - Always accept connections properly with
NetworkTransport.AcceptConnection()before communicating with a client.
内容的提问来源于stack exchange,提问作者Jeffrey W.

