#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 допускает разные параметры поставщика. Поэтому, когда ваш клиент и сервер от разных поставщиков, размер изменяется на несколько байтов. но предполагается, что каждый поставщик может работать с любым другим поставщиком. Флаг, я думаю, должен был игнорировать ошибки, когда размер был другим. Но совместимость не должна создавать ошибок.