Как TcpClient улучшается на необработанных сокетах? - PullRequest
1 голос
/ 09 января 2020

Я видел в нескольких местах людей, которые говорят, что TcpClient и NetworkStream предпочтительнее, чем необработанное Socket использование, например, что они помогают с точки зрения «кадрирования данных», когда сообщения, полученные от сервера, могут быть в любое количество фрагментов, которые нужно проанализировать и объединить в исходные сообщения (вызовы Send / Receive не гарантируются 1: 1)

Что я не понимаю, так это как лучше в этой связи? Конечно, он не может волшебным образом соединять сообщения обратно, так как эта информация не передается по TCP. Он не может ожидать отправки дополнительных данных о длине сообщения, в противном случае он не будет совместим с большинством TCP-серверов, только с теми, которые используют TcpListener. Socket Так может ли кто-нибудь объяснить, как это облегчает мою жизнь начинающего TCP-кодера?

1 Ответ

2 голосов
/ 11 января 2020

Возможно, это немного похоже на вопрос, зачем использовать System.Net.Sockets (который предоставляет API для WinSock вместо написания нашего собственного WinSock API.

TcpClient, абстрагируясь от множества различных способов * устанавливают sh сокет и делает доступными только несколько очень распространенных. Кроме того, это облегчает обработку таких вещей, как буферы. Аналогично NetworkStream абстрагирует множество различных способов чтения / записи из сокета и позволяет использовать более известные потоки. на вершине NetworkStream. Такие как TextWriter и TextReader.

Они на самом деле не имеют никакого значения с точки зрения кадрирования данных. Вам все еще нужно знать, где данные, которые вы ищете начинается и заканчивается. Хотя если ваши данные представляют собой старую добрую старую строку текста, то TextReader и TextWriter поверх NetworkStream делают это совершенно счастливым.

IMO, самое большое единственное преимущество для TcpClient и NetworkStream - это Asyn c методов и невероятно простых средств для разработки неблокирующего кода клиент / сервер ввода-вывода. В то время как вы можете сделать это прямо t Сокеты, это намного сложнее и сложнее.

Если вы только начинаете, я бы рекомендовал вообще пропустить NetworkStream (для чтения) и использовать System.IO.Pipelines - который расположен поверх NetworkStream, это еще больше отвлекает NetworkStream и ускоряет разработку.

Конечно, вы можете делать все, что TcpClient и NetworkStream, предоставляя себя, напрямую взаимодействуя с Socket, но вы обнаружите, что пишете много дублирующий код с множеством крайних случаев, которые уже были продуманы в TcpClient и NetworkStream.

...