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