[英]Java TCP Client and C# Server; Client Only Receives Message After Server Closes
[英]C# TCP server receives two messages send by Python client at once
我正在尝试接收由 Python TCP 客户端发送到 C# 服务器的多条消息。 我确实收到了数据,但是一下子就收到了,我不希望这种情况发生。 我试图将服务器缓冲区大小设置为我发送的 byte[] 的大小,但它没有用( source )。 任何想法如何解决这个问题?
客户端发送代码:
import socket
def send_to_remote(sock, data):
data_bytes = bytearray()
data_bytes.extend(map(ord, data)) # appending the array with string converted to bytes
bytes_length = len(data_bytes) # length of the array that I am sending
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, bytes_length) # setting the buffer size to the array length
print(bytes_length)
sock.send(data_bytes) # sending the data
服务器接收代码:
public static string ReadData(TcpClient connection)
{
StringBuilder receivedDataStr = new StringBuilder();
NetworkStream connectionStream = connection.GetStream();
if (connectionStream.CanRead)
{
byte[] connectionBuffer = new byte[connection.ReceiveBufferSize];
Console.WriteLine(">> Reading from NODE");
int bytesRead = 0;
bytesRead = connectionStream.Read(connectionBuffer, 0, 1024);
receivedDataStr.Append(Encoding.ASCII.GetString(connectionBuffer, 0, bytesRead));
Console.WriteLine(">> " + connection.ReceiveBufferSize);
return receivedDataStr.ToString();
}
else
{
Console.WriteLine(">> Can't read from network stream");
return "none-read";
}
}
编辑:
我要做的是:
send_to_remote(socekt, "msg1")
send_to_remote(socekt, "msg1")
进而:
string msg1 = ReadData(client);
string msg2 = ReadData(client);
我收到 106200 的缓冲区数组。
结果是:
"msg1 (then new line) msg2"
"" (string msg2 is waiting for data)
先感谢您!!
TCP 是流协议,而不是数据包协议。 绝对不能保证您会以与发送的完全相同的块获取数据 - 所有保证的是您将以正确的顺序获取字节(或失败或超时等) . 您可以单独获取每个字节,或一次获取 14 条消息。 或者介于两者之间的任何内容,包括一次接收消息的一半,以及下一次接收消息的另一半。 在 unicode(等)的情况下,这也意味着单个字符可以拆分为多个接收。
任何基于 TCP 的多消息协议都需要包含某种框架,即某种让您知道每个单独消息的开始和结束位置的方法。 由于您使用的是基于文本的协议,因此一个常见的选择是使用 CR、LF 或 CR+LF 分隔逻辑消息 - 然后缓冲数据直到您拥有完整的消息 - 通过查找行结束。 为了完整性:在二进制协议的情况下,通常使用某种指示有效载荷中数据量的标头对有效载荷进行长度前缀,然后您只需要解析标头,确定长度并缓冲,直到您有那么多数据。
在具有文本协议且没有挑战性可扩展性问题的简单应用程序中,可以使用StreamReader
(在NetworkStream
之上)为您完成该部分,然后只需使用ReadLine
或ReadLineAsync
。 但是请注意,这在“真实”服务器(尤其是ReadLine
)中是一个坏主意 - 您不希望恶意或只是有问题的客户端永远锁定线程,因为它发送了几个没有行结尾的字符,然后没有发送任何其他东西......从来没有。 当然,在一个严肃的服务器,你就不会使用每个客户端线程反正。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.