gpt4 book ai didi

c# - 不完整的消息(C# TCP/IP 客户端)

转载 作者:可可西里 更新时间:2023-11-01 02:37:30 25 4
gpt4 key购买 nike

首先,我绝对不是网络程序员。我尝试做的是在 Java 服务器和 C# 客户端之间进行非常简单的 TCP/IP 通信。

Java 服务器:

 public void run(){   
try {
// Open server socket
_server = new ServerSocket(SERVER_PORT);
_client = _server.accept();
System.out.println("ComInterface: client connected.");
// Wait for a client data output stream
while(true){

// Receive message from client
BufferedReader is =
new BufferedReader(new InputStreamReader(_client.getInputStream()));
msg = is.readLine();

// Process message
if(msg!=null){
System.out.println("ComInterface: Message Received : <" + msg + ">.");
processMessage(msg); // Independant method
}
else{
System.out.println("ComInterface: client closed connection.");
_client.close();
_client = _server.accept();
System.out.println("ComInterface: client connected.");
}

}

} catch (IOException e) {
e.printStackTrace();
}
}

public void sendMessage(String msg){
try {

// Out stream
DataOutputStream os = new DataOutputStream(_client.getOutputStream());

os.writeBytes((String)(msg+"\n"+(char)13));
os.flush();
System.out.println("ComInterface: Message <" + msg + "> sent");

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

这是 C# 客户端:

public class ComInterface : MonoBehaviour
{
public const String SERVER_IP = "127.0.0.1"; // Localhost
public const int PORT = 1100; // Default port
public const int READ_BUFFER_SIZE = 5000; // 4.8828125 kilobytes

private TcpClient _client;
private ASCIIEncoding _asen;
private byte[] _readBuffer;
private String _msg;

public Boolean connected { get; internal set; } // setter is for internal use only

/**
* Initialize internal variables (buffer, socket...)
*/
public ComInterface()
{
connected = false;
_client = new TcpClient();
_asen = new ASCIIEncoding();
_readBuffer = new Byte[READ_BUFFER_SIZE];
_msg = String.Empty;
}

/**
* Connect to server at SERVER_IP:PORT
* Return true if connection was a success, or false if failure.
*/
public Boolean Connect()
{
try
{

_client.Connect(SERVER_IP, PORT);
connected = true;
Array.Clear(_readBuffer, 0, _readBuffer.Length);
Debug.Log("TCPClient: <Connect> Connected to the server");
// Start an asynchronous read invoking ReceiveComMessage
_client.GetStream().BeginRead(_readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(ReceiveComMessage), _client.GetStream());
}
catch (Exception ex)
{
Debug.Log("TCPClient: <Connect> Cannot connect to the server - " + ex.Message);
connected = false;
}
// Return connection state
return connected;
}

/**
* Received a message from Communicator
*/
private void ReceiveComMessage(IAsyncResult ar)
{
int BytesRead;
String msg;
try
{
BytesRead = _client.GetStream().EndRead(ar);
if (BytesRead < 1)
{
// if no bytes were read server has close.
Debug.Log("TCPClient: <ReceiveComMessage> The server has closed (BytesRead<1)");
this.Disconnect();
return;
}
// Convert the byte array the message was saved into,
msg = Encoding.ASCII.GetString(_readBuffer);
Debug.Log("C# Message: \"" + msg + "\""); // Output example in log below
BytesRead = 0;
Array.Clear(_readBuffer, 0, _readBuffer.Length);

// Start a new asynchronous read into readBuffer.
_client.GetStream().BeginRead(_readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(ReceiveComMessage), _readBuffer);

}
catch (Exception ex)
{
Debug.Log("TCPClient: <ReceiveComMessage> The server has closed (Exception):" + ex.Message + " see " + ex.StackTrace);
this.Disconnect();
}

主要问题是所有到达的消息都不完整。这是日志跟踪:

C#: Message "{
C#: Message ""sender":"Bob"",
C#: Message ""recipient":",
etc...

而不是例如

C#: Message "{"sender":"Bob","recipient":[1,2,3]}"

我有点困惑,我需要一些帮助来解决这个问题。非常感谢!

最佳答案

TCP是面向流的连接,不是面向消息的。它没有消息的概念。当您写出序列化字符串时,它只会看到无意义的字节序列。 TCP 可以自由地将流分成多个片段,并且它们将以这些片段大小的 block 的形式在客户端接收。在另一端重建整个消息取决于您。

在您的场景中,通常会发送一个消息长度前缀。这样,客户端首先读取长度前缀,这样它就可以知道传入的消息应该有多大。

我会认真考虑使用像 Google 的 Protocol Buffers 这样的东西作为声明消息然后使用大小前缀选项流式传输它们的好方法。好处是您定义了一次消息集,然后使用可用的 tools从消息定义自动生成 C++、Java、C# 等代码。这将有助于拥有适用于不同语言的一致消息集。

关于c# - 不完整的消息(C# TCP/IP 客户端),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11237156/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com