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個のメッセージを取得することもできます。または、1つの受信のメッセージの半分と、次の受信の残りの半分を含む、その間の何か。ユニコード(など)の場合、これは、1つの文字を複数の受信に分割できることも意味します。
TCPに基づくマルチメッセージプロトコルには、何らかのフレーミングを含める必要があります。つまり、個別のメッセージがどこで開始および終了するかを知るための何らかの方法が必要です。テキストベースのプロトコルを使用しているため、一般的なオプションは、論理メッセージをCR、LF、またはCR + LFで区切ることです。次に、メッセージ全体が得られるまでデータをバッファリングするのが仕事です。行末。完全を期すために:バイナリプロトコルの場合、ペイロード内のデータ量を示す何らかのヘッダーでペイロードの長さプレフィックスを付けるのが一般的です。その後、ヘッダーを解析し、長さを決定し、次のようになるまでバッファリングする必要があります。それだけのデータがあります。
テキストプロトコルを使用し、スケーラビリティに関する問題がない単純なアプリケーションでは、StreamReader
(の上にNetworkStream
)を使用してその部分を実行してから、ReadLine
またはを使用できる場合がありReadLineAsync
ます。ただし、これは「本物」のサーバ(特にに悪い考えであろうとReadLine
) -あなたは、悪意のあるまたはちょうどバギークライアントは、それが数文字を送ったという理由だけで永遠にスレッドをロックしたくない行末せず、その後のdidn他に何も送らないでください...今までに。もちろん、深刻なサーバーでは、とにかくクライアントごとにスレッドを使用することはありません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加