Это не еще один TcpClient vs Socket.
TcpClient - это оболочка вокруг класса Socket для облегчения разработки, а также доступ к базовому Socket.
еще ...
На странице библиотеки MSDN для класса TcpClient можно прочитать следующее замечание:
Класс TcpClient предоставляет простые методы для подключения, отправки и получения потоковых данных по сети в синхронном режиме блокировки.
А для класса Socket:
Класс Socket позволяет выполнять как синхронную, так и асинхронную передачу данных с использованием любого из протоколов связи, перечисленных в перечислении ProtocolType.
Чтобы отправлять / получать некоторые данные асинхронно только через TcpCient, необходимо вызвать GetStream, чтобы получить базовый NetworkStream, из / на котором данные могут быть прочитаны / записаны асинхронно, вызывая методы ReadAsync и WriteAsync на нем, следуя шаблону TAP (возможно использование конструкций async / await).
Чтобы отправлять / получать данные асинхронно через Socket (я не эксперт, но думаю, что понял правильно), мы можем напрямую читать / писать из / в самом экземпляре сокета, вызывая BeginRead / EndRead BeginWrite / EndWrite (или просто ReadAsync или WriteAsync .. не раскрывает шаблон TAP - т.е. не возвращает задачу .. сбивает с толку).
Прежде всего, есть идеи, почему класс Socket в .NET 4.5 никоим образом не реализует шаблон TAP, то есть ReadAsync и WriteAsync, возвращающие Task (событие, если вызывается по-другому, чтобы сохранить обратную совместимость)?
В любом случае, достаточно просто создать метод Task из пары методов модели APM, поэтому скажем, я вызываю этот асинхронный метод (для чтения) ReadAsyncTAP (возвращающий задачу).
Ok ? Итак, теперь предположим, что я хочу закодировать клиентский метод async Task<Byte[]> ReadNbBytes(int nbBytes)
, который я буду вызывать из своего кода для асинхронного чтения определенного количества байтов из сети.
Реализация этого метода, основанная исключительно на TcpClient, получит NetworkStream путем вызова GetStream и будет содержать асинхронный цикл, ожидающий вызова (ов) ReadAsync, пока буфер не заполнится.
Реализация этого метода на основе Socket будет содержать асинхронный цикл, ожидающий на ReadAsyncTAP, пока буфер не заполнится.
В конце концов, с точки зрения клиентского кода, я полагаю, это не имеет значения. В обоих случаях вызов await ReadNbBytes
немедленно «вернется». Однако я полагаю, что это имеет значение за кулисами ... Для TcpClient, полагающегося на NetworkStream, блокирует ли чтение как-то или нет в любой момент по сравнению с прямым использованием сокета? Если нет, то замечание, сделанное для TcpClient, неверно, когда речь идет о синхронном режиме блокировки?
Был бы очень признателен, если бы кто-нибудь мог прояснить!
Спасибо.