TCP представляет собой (двунаправленный) поток данных. Вы должны продолжать читать из него в al oop и анализировать данные по мере необходимости. Он не имеет понятия сообщений - десять записей на одной стороне могут привести к одному чтению на другой стороне так же легко, как одна запись на одной стороне может привести к десяти чтениям на другой стороне.
У вас есть контракт с TCP следующим образом:
- Если в буфере приема есть данные,
Read
немедленно возвращается, заполняя предоставленный вами буфер таким количеством данных, сколько доступно, вплоть до длины буфера. Число прочитанных байтов является возвращаемым значением Read
. - Если в приемном буфере нет данных,
Read
будет блокироваться, пока не будет хотя бы одного байта данных. Затем следует, как в первом случае. - Если другие стороны выключат сокет,
Read
вернет ноль.
Итак, чтобы заставить работать TCP, вам нужно все oop. Как именно вы сформируете l oop, зависит от того, что вы пытаетесь сделать. Если вы действительно работаете с данными, которые логически представляют собой поток (например, аудиоданные), просто продолжайте читать как можно быстрее и обрабатывайте любые данные, которые вы получаете, по мере их поступления. Если вам нужно отправлять сообщения, вам необходимо реализовать протокол сообщений. Если вам нужно одноразовое сообщение, вы можете просто продолжить чтение, пока Read
не вернет ноль.
Ваш случай может быть обработан при первом подходе - продолжайте чтение, пока поток не закроется, и pu sh полученные данные переслать. Предполагая, что данные на самом деле являются потоком текста UTF8, получатель basi c будет выглядеть примерно так:
using (var client = new TcpClient())
{
tcpClient.Connect(myIP, port);
var stream = client.GetStream();
var buffer = new byte[4096]; // Adapt the size based on what you want to do with the data
var charBuffer = new char[4096];
var decoder = Encoding.UTF8.GetDecoder();
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
var expectedChars = decoder.GetCharCount(buffer, 0, bytesRead);
if (charBuffer.Length < expectedChars) charBuffer = new char[expectedChars];
var charCount = decoder.GetChars(buffer, 0, bytesRead, charBuffer, 0);
Console.Write(new string(charBuffer, 0, charCount));
}
client.Close();
}
Обратите внимание, что это не обрабатывает ошибки, поэтому не используйте его как есть в любом производственный код. Возможно, вы также захотите использовать методы Async
, если вы ожидаете более нескольких одновременных подключений. Это просто для иллюстрации базового c способа обработки потока данных, получаемых по TCP.
Если вы хотите получить более глубокое представление о работе с TCP, у меня есть несколько очень простых примеров на https://github.com/Luaancz/Networking. Я не нашел хороших учебных пособий или примеров кода для C#, поэтому, если этого недостаточно, вам, вероятно, придется глубже изучить документацию по сокетам, TCP и всем прочим.
Или просто используйте существующую сетевую библиотеку, а не пытайтесь написать свою собственную :) TCP по-прежнему очень низкий уровень.