2010-06-24 166 views
1

我正在C#中开发一个Tcp客户端,我正在使用TcpClient类。 我无法连接到服务器。TcpClient不连接

调试应用程序我可以看到对Connect的调用是成功的,但在执行此操作后,我检查了服务器和客户端上的连接状态netstat。结果是服务器的连接是ESTABLISHED,但在客户端上我看不到netstat结果中服务器的任何连接。

阅读TcpClient实例我可以看到属性Connected是真的,所以它应该没问题,但是当我尝试从NetworkStream中读取时,它会挂起。

当我说它挂起我的意思是服务器正在发送数据,但readline根本没有得到任何数据。

你知道可能是什么问题和一些解决方法吗?

感谢

+0

任何防火墙之间? – Bobby 2010-06-24 13:21:33

+0

你连接了什么? – 2010-06-24 13:28:26

+0

我正在连接到运行在Solaris之上的服务器应用程序。中间没有防火墙。 – user311906 2010-06-24 21:23:13

回答

2

首先,推荐:根据我的经验,TcpClient最适合异步使用。

虽然在我所有的使用TcpClient中,但我从来没有在没有首先写请求的情况下读取响应。您将永远阻止尝试同步等待对未发送请求的响应。

扩展上,发送请求会做这样的:

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

将发送这是在tcpMessage的要求,这将是从一个字符串产生这样的字节流:

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

其中有你这样的请求消息:

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

这发出你的要求,这将导致服务器生成的响应,然后您可以收集这样的:

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

你应该最终能够得到的东西回来! 即使它只是一个“我不喜欢你的请求!”响应。 8 D

+0

听起来你的建议看起来不错。基本上我的客户只能听服务器。当我说ReadLine挂起我的意思是你说什么:服务器正在发送数据,但我永远等待。 还有一个问题:当你说“用请求书写”时,你对于请求的代码意味着什么?你的意思只是NetworkStream.Write()..就像一些心跳? – user311906 2010-06-24 14:48:35

+0

你走了,回答扩大了。这不是心跳信号,它是您的TCP请求消息。在我的例子中,它是一个HTTP GET。希望能为你解决它。 – Task 2010-06-24 15:32:58

1

这取决于在服务器上,但大多数TCP服务器将等待它发送一个响应之前,客户端发送一个请求。这听起来像你的线程正在等待数据。您是否设置了读取超时?

请确保您发送请求,以便服务器知道向您发送回复。

通常情况下,您会将您的TcpClient放入单独的线程中,并使用读取超时来避免挂起整个程序等待响应。

确保在与阻塞(同步)服务器通信时不使用非阻塞(异步)套接字,那么只会遇到问题。阻塞套接字对于Web来说是正常的,因为大多数Web服务都使用请求/响应范例。

+0

不,我忘了提及,当我说readLine挂起我的意思是服务器正在发送数据,但readline没有得到任何数据。 – user311906 2010-06-24 14:45:15

+0

你确定服务器正在发送数据吗?大多数网络都与请求/响应范例一起工作。您必须在服务器响应之前发送请求。 – 2010-06-24 14:55:31

1

你看到的是绝对正常的。

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. 

当您尝试读取时,线程将被阻止,直到服务器向您发送一些数据。否则,根据您使用的读取方法,它可以永久封锁。

+0

我不清楚。当我说它挂起时,我的意思是服务器正在发送数据,但readline根本没有得到任何数据。 – user311906 2010-06-24 14:44:29

0

在客户端,当你使用netstat的时候你在找什么端口?

因为当客户端进行连接时,它会使用临时端口。这意味着它将使用高于最大众所周知的端口号的任何空闲端口。所以,你的客户可能会使用不同的端口号。

而对于网络流问题,我将不得不查看代码来确定哪里出了问题。