开发者

reading messages from Device over gprs

开发者 https://www.devze.com 2023-03-19 13:43 出处:网络
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 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 connect开发者_如何学编程ion...-- ");
        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.


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


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

0

精彩评论

暂无评论...
验证码 换一张
取 消