我有一个GPS设备,将安装在许多卡车上。
我可以配置设备通过gprs将数据语句“gps data,device id”发送到IP和端口。
我正在使用TcpListener
类来读取服务器端的数据。
TcpListener server = null;
private void listen_data()
{
Int32 port = controller_port;
IPAddress localAddr = IPAddress.Parse(this_ip);
server = new TcpListener(localAddr, port);
server.Start();
Byte[] bytes = new Byte[256];
String data = null;
while (true)
{
Console.Write("Waiting for a connection...-- ");
TcpClient client = server.AcceptTcpClient();
Console.Write("Connected!");
data = null; int i;
NetworkStream stream = client.GetStream();
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
}
}
}
该方法正在侦听服务器ip和端口上的内容。
我想知道我是否将设备配置为在同一个端口上发送到服务器。我能够收听所有设备,还是第一个连接的设备将是唯一的设备?
这种方法是从设备读取即将到来的数据的最佳方法吗?
我是否需要为每个设备配置不同的端口并为每个设备端口创建一个新的监听线程?
有时我会遇到例外情况“请求频道在等待回复时超时”
非常感谢您的帮助。
答案 0 :(得分:2)
在您的代码中,您正在收听所有设备,但只有在完成从第一个设备读取所有数据后才会收到“请求通道在等待回复时超时”。您应该有一个不同的线程每个句柄tcpClient
。
所以代码应该是这样的:
TcpListener server = null;
private void listen_data()
{
Int32 port = controller_port;
IPAddress localAddr = IPAddress.Parse(this_ip);
server = new TcpListener(localAddr, port);
server.Start();
while (true)
{
Console.Write("Waiting for a connection...-- ");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("new client connected");
ThreadPool.QueueUserWorkItem(new WaitCallback(HandleClient), client);//or use Task if 4.0 or new Thread...
}
}
private void HandleClient(object tcpClient)
{
TcpClient client = (TcpClient)tcpClient;
Byte[] bytes = new Byte[256];
String data = null;
int i;
NetworkStream stream = client.GetStream();
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
}
Console.WriteLine(data);
}
答案 1 :(得分:0)
1)两者。您应该能够监听所有设备,但是您经常无法使用您的代码,因为侦听器线程正在等待来自之前连接的设备的流。
2)可能不是。 IIRC,NetworkStream.Read在对端设备关闭连接时返回0。这是你的协议 - 即。设备连接,发送一些数据并断开连接?如果是这样,虽然会很慢。无论如何,还有另一个问题。您应该将流上接收到的字节连接到数据,而不仅仅是替换它们 - Read()我的返回多次进行一次通信,甚至每次都使用一个字节,(不太可能,但TCP流允许)。你可以保持字节数rx。到目前为止,并使用'offset'参数来执行此操作。
3)你只需要一个监听线程,即。调用AcceptTcpClient()的那个。该线程不应该进行阻塞调用以从AcceptTcpClient()返回的套接字接收数据。创建/分配/ depool /无论新的客户端 - 服务器线程如何为AcceptTcpClient()返回的每个“客户端”套接字运行Read()循环,或者使用异步IO。
4)当新的连接在NetworkStream上等待时,您的单个侦听器/读取线程将无响应 - 其他设备将无法连接。监听器应该快速返回AcceptTcpClient(),而不是等待慢速网络/设备发送数据。
RGDS, 马丁