TcpClient не подключается - PullRequest
1 голос
/ 24 июня 2010

Я разрабатываю Tcp-клиент на C # и использую класс TcpClient. Я не могу подключиться к серверу.

Отладка приложения. Я вижу, что вызов Connect выполнен успешно, но после этого я проверяю netstat состояние соединения как на сервере, так и на клиенте. В результате соединение с сервером ESTABLISHED, но на клиенте я не вижу никакого соединения с сервером в результате netstat.

Читая экземпляр TcpClient, я вижу, что свойство Connected имеет значение true, поэтому оно должно быть в порядке, но когда я пытаюсь прочитать с NetworkStream, оно зависает.

Когда я говорю, что он зависает, я имею в виду, что сервер отправляет данные, но readline вообще не получает никаких данных.

Вы знаете, в чем может быть проблема и какой-то обходной путь?

Спасибо

Ответы [ 4 ]

2 голосов
/ 24 июня 2010

Во-первых, рекомендация: по моему опыту, TcpClient лучше всего использовать асинхронно.

При всем моем использовании TcpClient я никогда не мог прочитать ответ, не выполнив сначала запись с запросом. Вы навсегда заблокируете попытку синхронно ожидать ответа на запрос, который вы не отправили.

На этом основывается отправка запроса:

TcpClient.GetStream().BeginWrite( tcpMessage, ... );

, который отправит запрос, который находится в tcpMessage, который будет являться байтовым потоком, полученным из строки, подобной этой:

byte[] tcpMessage = httpEncoding.GetBytes( httpMessage );

Которое имеет ваше сообщение-запрос:

httpMessage = "GET / HTTP/1.1\r\n" + ...;

Это отправляет ваш запрос, который заставляет сервер генерировать ответ, который вы можете затем собрать следующим образом:

TcpClient.GetStream().BeginRead( ... );

И вы наконец-то сможете получить что-то обратно! Даже если это всего лишь "Мне не понравился твой запрос!" ответ. 8 Д

1 голос
/ 24 июня 2010

То, что вы видели, абсолютно нормально.

Reading the TcpClient instance I can see that the property Connected is true so it should be fine but when I try to read from the NetworkStream it hangs.

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

1 голос
/ 24 июня 2010

Это зависит от сервера, но большинство TCP-серверов будут ждать, пока клиент отправит запрос, прежде чем отправит ответ.Похоже, ваша ветка ждет данных.Вы установили тайм-аут чтения?

Убедитесь, что вы отправили запрос, чтобы сервер знал, что нужно отправить вам ответ.

Обычно вы помещаете свой TcpClient в отдельный поток и используетепрочитайте тайм-аут, чтобы избежать зависания всей программы в ожидании ответа.

Убедитесь, что вы не используете неблокирующие (асинхронные) сокеты при взаимодействии с блокирующим (синхронным) сервером, вы столкнетесь только спроблемы.Блокирующие сокеты являются нормальным явлением для Интернета, поскольку большинство веб-служб используют парадигму запрос / ответ.

0 голосов
/ 24 июня 2010

на стороне клиента, какой порт вы искали, когда делали netstat?

Потому что, когда клиент устанавливает соединения, он использует эфемерный порт. Это означает, что он будет использовать любой свободный номер порта выше максимально известного номера порта. Таким образом, ваш клиент может использовать другой порт #, чем вы ожидаете.

А для решения проблемы сетевого потока мне нужно увидеть код, чтобы определить, что пошло не так.

...