Как подключиться к сокету с начальными байтами - PullRequest
1 голос
/ 18 апреля 2020

Я обнаружил, что можно получить исходные данные, переданные с помощью EndAccept.

Это из документов :

EndAccept (Byte [ ], IAsyncResult)

Асинхронно принимает попытку входящего соединения и создает новый объект Socket для обработки связи с удаленным хостом. Этот метод возвращает буфер, который содержит переданные начальные данные. C#

Как я могу отправить эти начальные байты? BeginConnect не дает мне возможность. Есть ли другой метод, который я могу использовать?

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

При использовании API. NET Socket важно помнить, что этот API является , а не нативным для. NET. Это оболочка для Windows Winsock 2 API, которая сама является Windows реализацией оригинального API сокетов Беркли . Это означает, что на базовом уровне сети могут быть доступны функции, которые необязательно предоставляются API. NET.

Кроме того, важно помнить, что класс Socket предлагает несколько способов Совершено sh то же самое. В частности, метод Socket.Connect() - не единственный механизм, который можно использовать для создания соединения. Существует также метод Socket.ConnectAsync(), который использует SocketAsyncEventArgs для предоставления состояния для операций сокета, включая запрос на соединение, и эта структура данных действительно предоставляет средства для клиента запрашивая соединение также предоставить буфер данных для отправки.

Даже без этого метода Socket удаленная конечная точка может не использовать API. NET для выполнения запроса соединения. Другие API сокетов, такие как функция WSAConnect() в Winsock 2, предоставляют клиенту механизм включения буфера данных для передачи вместе с запросом соединения.

Я сомневаюсь, что вы когда-нибудь найдете эти данные в сценарии, описанном в другом ответе. Т.е. если клиент делает запрос на соединение отдельно от какой-либо фактической операции отправки, впоследствии отправленные данные не будут включены в запрос на соединение. Это связано с тем, что клиент не может отправлять данные в сокет до тех пор, пока не будет завершен запрос на подключение, чего он не может, пока сервер не вызовет EndAccept(). Любые данные, которые доставляются вместе с EndAccept() , должны быть предоставлены как неотъемлемая часть исходного запроса на подключение.

Вы правы, что синхронный метод Socket.Connect() не обеспечивает способ сделать это, но есть и другие доступные механизмы подключения, включая Socket.ConnectAsync(), а также API-интерфейсы, отличные от. NET, которые позволяют включать буфер данных как часть запроса на подключение. Это те данные, которые будут получены сервером как часть вызова метода EndAccept().

0 голосов
/ 18 апреля 2020

Я полагаю, что если вы вызовете BeginAccept с одной из двух перегрузок, ожидающих отправки начального блока данных, то соответствующий EndAccept предоставит этот блок данных. Если вы вызываете эту перегрузку, это означает, что на стороне сервера вызов API, принимающий клиента, не завершится, пока клиент не отправит некоторые данные. Я полагаю, что это более эффективно в коде вашего сервера, поэтому вы не проснетесь, пока не получите полезные данные для go вместе с клиентом, который вы приняли. Это может сэкономить вам переключение контекста на огромных серверах и повысить эффективность.

Если вы просто вызываете перегрузку BeginAccept , которая не запрашивает ожидание исходных данных тогда соответствующий EndAccept не предоставит никаких первоначально перенесенных данных.

Это очевидно из документации для AcceptEx (это функция, которая называется внутри BeginAccept ) в следующем отрывке:

Если предоставляется буфер приема, операция перекрытия не будет завершена, пока не будет принято соединение и данные не прочитаны.

Итак, ответ на ваш вопрос "Как я могу отправить эти начальные байты?" технически просто есть клиент "отправить".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...