Получение данных от машины с помощью сокета

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

Проблемы, с которыми я сталкиваюсь

  1. Моя программа не получает полных данных. Может быть, из-за этой строчки if (sock.Receive(buffer).ToString().Length > 1) . Но я использовал эту линию, потому что она всегда что-то получает.
  2. Моя программа переходит в бесконечный цикл. Я ищу программу, которая должна остановиться на некоторое время после получения данных и снова начать прослушивать новые входящие данные.

Комментарии:

1. Вы создали буфер, его свойство длины всегда имеет тот размер, который вы ему дали (2048). Receive() Метод возвращает количество байтов, считанных из сокета, поэтому сделайте что-нибудь вроде var bytesRead = sock. Получать(буфер); тестировать(байт-поток); использовать(буфер, байт-поток);`

2. @AlanK я уже сделал здесь while ((recv = sock.Receive(buffer)) > 0)

3. Вам нужно знать формат кадрирования того, что вы ожидаете. Машина, отправляющая вам данные, должна иметь способ обработки данных. Вам необходимо использовать это обрамление для создания ваших требований к чтению.

Ответ №1:

Здесь есть несколько вещей;

  1. вам нужно сохранить количество прочитанных и использовать только это количество байтов, т. Е. var bytes = sock.Receive(buffer); (и использовать bytes как для теста EOF, так и для того, сколько байтов нужно обработать)
  2. мы не можем использовать ToString().Length > 1 здесь, потому что это целое число, и каждое целое число, как строка, имеет ненулевую длину; вместо этого просто: if (bytes > 0) (мелочи: существует сценарий, в котором открытый сокет может возвращать ноль без значения EOF, но… здесь это неприменимо)
  3. даже для текстового протокола, вы можете не должен просто использовать Encoding.UTF8.GetString(buffer, 0, bytes) , потому что utf8 является многобайтовой кодировкой, означает: вы могли бы частичной символов; кроме того, ты еще не знаешь ли, что это одно сообщение, половину сообщения, или на 14 и чуть сообщения; Вы должны прочитать о протоколе «обрамление» — что может означать «буфера байт, пока не появится новая строка ( 'n' ) символов, расшифровать эти буферизованные байты через кодирование, процесс это сообщение, и повторяю»