通过 gprs 从设备读取消息

发布于 2024-11-19 22:35:53 字数 1086 浏览 1 评论 0原文

我有一个 GPS 设备,将安装在许多卡车上。 我可以配置设备通过 gprs 将数据语句“gps 数据,设备 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 和端口上的情况。

  1. 我想知道我是否将设备配置为在同一端口上发送到服务器。我是否能够监听所有设备,或者第一个连接的设备将是唯一的?

  2. 此方法是从设备读取传入数据的最佳方法吗?

  3. 我是否需要为每个设备配置不同的端口并为每个设备端口创建一个新的侦听线程?

  4. 有时我会遇到异常“请求通道在等待回复时超时”

非常感谢您的帮助。

i have a GPS device that will be installed in many trucks.
i can configure the device to send data statement "gps data, device id" over gprs to IP and Port.
i'm using TcpListener class to read the data on the server side.

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);
        }
    }
}

that method is listening to what is coming on server ip and port.

  1. i want to know if i configured the devices to send to the server on the same port.am i able to listen to all the devices or the first device to connect will be the only one ?

  2. is this method the the best way to read the coming data from the devices?

  3. do i need to configure a different port for each device and create a new listen thread for each device port?

  4. sometimes i'm facing exceptions "the request channel timed out while waiting for a reply"

many thanks in advance for your help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陈年往事 2024-11-26 22:35:53

在您的代码中,您正在侦听所有设备,但只有在完成从第一个设备读取所有数据后,您才会收到“请求通道在等待答复时超时”。您应该有不同的线程,每个线程处理一个 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);
}

In your code you are listening to the all devices but only after finish read all data from the first device so you are receiving "the request channel timed out while waiting for a reply".You should have a different threads each one handle a tcpClient.

so the code should be something like:

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);
}
饭团 2024-11-26 22:35:53

1)两者。您应该能够侦听所有设备,但您的​​代码通常无法侦听,因为侦听器线程正在等待来自较早连接的设备的流。

2)可能不是。 IIRC,当对等设备关闭连接时,NetworkStream.Read 返回 0。这是你的协议吗?设备连接、发送一些数据然后断开连接?如果是这样,那就会起作用,尽管速度很慢。无论如何,还有一个问题。您应该将流上收到的字节连接到数据,而不仅仅是替换它们 - Read() 我多次返回一次通信,甚至可能每次只返回一个字节(不太可能,但 TCP 流允许)。您可以保留接收的字节数。到目前为止并使用“offset”参数来执行此操作。

3)你只需要一个监听线程,即。调用 AcceptTcpClient() 的那个。该线程不应进行阻塞调用以从 AcceptTcpClient() 返回的套接字接收数据。创建/分配/释放池/任何新的客户端-服务器线程来为 AcceptTcpClient() 返回的每个“客户端”套接字运行 Read() 循环,或者使用异步 IO。

4) 您的单个侦听器/读取线程在等待 NetworkStream 时将不会响应新连接 - 其他设备将无法连接。侦听器应该快速返回 AcceptTcpClient(),而不是等待慢速网络/设备发送数据。

平均值,
马丁

1) Both. You should be able to listen for all devices, but you often cannot with your code because the listener thread is tied up waiting for the stream from a device that connected earlier.

2) Probably not. IIRC, NetworkStream.Read returns 0 when the connection is closed by the peer device. Is this your protocol - ie. the device connects, sends some data and disconnects? If so that will work, though slowly. Anyway, there is another problem. You should be concatenating the bytes received on your stream to data, not just replacing them - Read() my return multiple times for one communication, perhaps even with a single byte each time, (unlikely, but permitted with TCP streams). You could keep a count of bytes rx. so far and use the 'offset' parameter to do this.

3) You only need one listening thread, ie. the one that calls AcceptTcpClient(). This thread should not be making blocking calls to receive data from the socket returned by AcceptTcpClient(). Either create/allocate/depool/whatever a new client-server thread to run your Read() loop for each 'client' socket returned by AcceptTcpClient() or use asynchronous IO.

4) Your single listener/read thread will be non-responsive for new connections while it is waiting on the NetworkStream - other devices will be unable to connect. The listener should get back to AcceptTcpClient() quickly and not wait for slow networks/devices to send data.

Rgds,
Martin

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文