Това не е още едно TcpClient срещу 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 връщащи задача (събитие, ако се извика по различен начин, за да се запази обратната съвместимост)?
Както и да е, достатъчно лесно е да се изгради метод на задача от двойка методи на APM модел, така че да кажем, че наричам този асинхронен метод (за четене) ReadAsyncTAP (връщане на задача).
Добре ? Така че сега да кажем, че искам да кодирам клиентски метод async Task<Byte[]> ReadNbBytes(int nbBytes)
, който ще извикам от моя код за асинхронно четене на определен брой байтове от мрежата.
Реализацията на този метод, базиран изключително на TcpClient, ще получи NetworkStream чрез извикване на GetStream и ще съдържа асинхронен цикъл, чакащ извикване(ия) на ReadAsync, докато буферът се запълни.
Изпълнението на този метод, базиран на Socket, ще съдържа асинхронен цикъл, чакащ ReadAsyncTAP, докато буферът се запълни.
В крайна сметка, от гледна точка на клиентския код, предполагам, че няма значение. И в двата случая обаждането до await ReadNbBytes
ще се „върне“ незабавно. Предполагам обаче, че има разлика зад кулисите ... За TcpClient, разчитащ на NetworkStream, блокира ли четенето по някакъв начин или не в даден момент, в сравнение с директното използване на socket? Ако не, грешна ли е забележката за TcpClient, когато говорим за режим на синхронно блокиране?
Ще се радвам много, ако някой може да изясни!
Благодаря.