简体   繁体   中英

C# TCP server receives two messages send by Python client at once

I am trying to receive multiple messages send by Python TCP client to a C# server. I do receive the data, but all at once and I don't want that to happen. I tried to set the server buffer size to the size of the byte[] which I am sending, but it didn't work ( source ). Any ideas how can I fix this issue?

Client sending code:

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

Server receiving code:

 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";
        }
    }

EDIT:

What I do is:

send_to_remote(socekt, "msg1")
send_to_remote(socekt, "msg1")

And then:

string msg1 = ReadData(client);
string msg2 = ReadData(client);

I receive buffer array of 106200.

The result is:

"msg1 (then new line) msg2"
"" (string msg2 is waiting for data)

Thank you in advance!!

TCP is a stream protocol, not a packet protocol. There is absolutely no guarantee that you're going to get data in the same exact chunks that it was sent - all that is guaranteed is that you'll get the bytes in the correct order (or a failure, or a timeout, etc). You can get each byte separately, or 14 messages at once. Or anything in between, including half of a message in one receive, and the other half in the next. In the case of unicode (etc), this also means that a single character can be split over multiple receives.

Any multi-message protocol based on TCP needs to include some kind of framing , ie some way for you to know where each separate message starts and ends. Since you're using a text-based protocol, a common option is to separate logical messages with a CR, LF, or CR+LF - and then it is your job to buffer data until you have an entire message - by looking for the line ending. For completeness: in the case of binary protocols, it is common to length-prefix payloads with some kind of header that indicates the amount of data in the payload, then you just need to parse the header, determine the length, and buffer until you have that much data.

In simple applications with a text protocol and no challenging scalability concerns, it may be possible to use StreamReader (on top of a NetworkStream ) to do that part for you, then just use ReadLine or ReadLineAsync . Note, however, that this would be a bad idea in "real" servers (especially ReadLine ) - you don't want a malicious or just buggy client locking a thread forever just because it sent a few characters without the line ending , and then didn't send anything else ... ever. Of course, in a serious server you wouldn't be using a thread per client anyway .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM