#c# #sockets
Вопрос:
Я очень новичок в программировании сокетов.
Я использую следующий код для получения входящих данных с машины патологии.
byte[] buffer = new byte[2048];
IPAddress ipAddress = IPAddress.Parse(SERVER_IP);
IPEndPoint localEndpoint = new IPEndPoint(ipAddress, PORT_NO);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
sock.Connect(localEndpoint);
}
catch (Exception ex)
{
throw ex;
}
int recv = 0;
string Printed = string.Empty;
StringBuilder sb = new StringBuilder();
while ((recv = sock.Receive(buffer)) > 0)
{
if (sock.Receive(buffer).ToString().Length > 1) // I used this line because it's receiving some garbage value all the time.
{
sb.Append(Encoding.UTF8.GetString(buffer));
}
else
{
if (sb.Length > 50 amp;amp; Printed == string.Empty)
{
Console.WriteLine(sb);
Printed = "Y";
}
}
}
Проблемы, с которыми я сталкиваюсь
- Моя программа не получает полных данных. Может быть, из-за этой строчки
if (sock.Receive(buffer).ToString().Length > 1)
. Но я использовал эту линию, потому что она всегда что-то получает. - Моя программа переходит в бесконечный цикл. Я ищу программу, которая должна остановиться на некоторое время после получения данных и снова начать прослушивать новые входящие данные.
Комментарии:
1. Вы создали буфер, его свойство длины всегда имеет тот размер, который вы ему дали (2048).
Receive()
Метод возвращает количество байтов, считанных из сокета, поэтому сделайте что-нибудь вроде var bytesRead = sock. Получать(буфер); тестировать(байт-поток); использовать(буфер, байт-поток);`2. @AlanK я уже сделал здесь
while ((recv = sock.Receive(buffer)) > 0)
3. Вам нужно знать формат кадрирования того, что вы ожидаете. Машина, отправляющая вам данные, должна иметь способ обработки данных. Вам необходимо использовать это обрамление для создания ваших требований к чтению.
Ответ №1:
Здесь есть несколько вещей;
- вам нужно сохранить количество прочитанных и использовать только это количество байтов, т. Е.
var bytes = sock.Receive(buffer);
(и использоватьbytes
как для теста EOF, так и для того, сколько байтов нужно обработать) - мы не можем использовать
ToString().Length > 1
здесь, потому что это целое число, и каждое целое число, как строка, имеет ненулевую длину; вместо этого просто:if (bytes > 0)
(мелочи: существует сценарий, в котором открытый сокет может возвращать ноль без значения EOF, но… здесь это неприменимо) - даже для текстового протокола, вы можете не должен просто использовать
Encoding.UTF8.GetString(buffer, 0, bytes)
, потому что utf8 является многобайтовой кодировкой, означает: вы могли бы частичной символов; кроме того, ты еще не знаешь ли, что это одно сообщение, половину сообщения, или на 14 и чуть сообщения; Вы должны прочитать о протоколе «обрамление» — что может означать «буфера байт, пока не появится новая строка ('n'
) символов, расшифровать эти буферизованные байты через кодирование, процесс это сообщение, и повторяю»