я получаю сообщение об ошибке при начале приема при использовании сокетов

#c# #sockets #tcp

#c# #сокеты #tcp

Вопрос:

Я создаю соединение сокета с устройством здесь, чтобы открыть дверь. Мне удается создать соединение и даже отправить команду, но я получаю странную ошибку в функции BeginReceive. В нем говорится, что «Предпринятая операция не поддерживается для типа объекта, на который ссылается» с кодом ошибки 10045.

Вот мой код:

 private byte[] data = new byte[1024];
  
 tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            TimeoutObject.Reset();
            tcp.BeginConnect(endPoint, tcpConnected, tcp);
            TimeoutObject.WaitOne(5);
            if (!tcp.Connected)
            {
                Console.WriteLine("Connection timed out");
                tcp.Close();
            }
            Thread.Sleep(100);
            tcp.Send(OPENDOOR);
            Thread.Sleep(3000);
            tcp.Send(CLOSEDOOR);

            Console.WriteLine("Send Successful");
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();

            tcp.Close();
  
 private void tcpConnected(IAsyncResult ar)
        {
            try
            {
                if (!tcp.Connected)
                    return;
                //doQueue(eventType.CONNECTED);
                Socket client = (Socket)ar.AsyncState;
                TimeoutObject.Set();
                client.EndConnect(ar);
                client.BeginReceive(data, 0, data.Length, SocketFlags.Truncated, new AsyncCallback(ReceiveData), client);
            }
            catch (ObjectDisposedException e)
            {
                Console.WriteLine(e.ToString());
                //doQueue(eventType.DEBUG, "Connect was cancelled"   e.Message);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                //doQueue(eventType.DEBUG, "Unhandled error"   e.Message);
            }
        }
  

методы tcp.send на самом деле делают то, что должны, я слышу, как открывается и закрывается дверной замок. Но ошибка beginreceive уже некоторое время меня озадачивает. У меня также есть функция receivedata, но я не буду публиковать это, потому что я никогда не попадаю в эту функцию, раньше она выдает исключение. Есть идеи?

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

1. Проверьте семейство адресов и убедитесь, что у вас есть IPV4 (не IPV6). Многие люди используют старый код со следующей строкой: IPAddress IPAddress = ipHostInfo. Список адресов [0]; Нулевой индекс на многих компьютерах равен IPV6, поэтому вам нужно изменить индекс на 1, который равен IPV4.

2. я нашел решение, но не уверен, почему это решение. По-видимому, socketflags.truncated вызывал ошибку. Я изменил его на None, и теперь он работает безупречно

3. Не знаю, почему вы использовали опцию truncate. Очень необычно. В заголовке TCP есть флаг, который разрешает усечение. Объем дейтаграмм TCP составляет не более 1500 байт. Усечение позволяет игнорировать максимальное значение 1500. Я никогда не использовал эту опцию. Значение 1500 может отличаться на несколько байт, поскольку спецификация TCP допускает разные параметры поставщика. Поэтому, когда ваш клиент и сервер от разных поставщиков, размер изменяется на несколько байтов. но предполагается, что каждый поставщик может работать с любым другим поставщиком. Флаг, я думаю, должен был игнорировать ошибки, когда размер был другим. Но совместимость не должна создавать ошибок.