2011-07-11 14 views
2

私は多くのトラックにインストールされるGPSデバイスを持っています。 私はgpr​​s上でデータステートメント "gps data、device id"をIPとPortに送信するようにデバイスを設定できます。 私はTcpListenerクラスを使用してサーバー側のデータを読み取ります。gprs経由でデバイスからメッセージを読む

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. 私は同じport.am上のサーバに送信するデバイスを構成した場合に接続するすべてのデバイスまたは最初のデバイスを聞くことができ、私は一つだけになります知りたいですか?

  2. この方法は、デバイスから次のデータを読み取るための最良の方法ですか?

  3. デバイスごとに異なるポートを設定し、デバイスポートごとに新しいリスンスレッドを作成する必要がありますか?あなたの助けを事前に

多くのおかげ

  • 時々私が直面してるの例外は「返事を待っている間に要求チャネルがタイムアウトしました」。

  • 答えて

    2

    あなたはすべてのデバイスに聞いているが、仕上げは、あなたが受けているように、第1のデバイスからすべてのデータを読み込み後にのみ、「要求チャネルは返事を待っている間にタイムアウトになりました」。それぞれ異なるスレッドを持って、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); 
    } 
    
    +0

    エラー「System.Threading.ThreadPool.QueueUserWorkItem(System.Threadingための最良のオーバーロードされたメソッドの試合:

    ので、コードは次のようになります。WaitCallback) 'に無効な引数があり、Error2Argument' 1 ':' void 'から' System.Threading.WaitCallback 'に変換できません。 – Ramah

    +0

    @Ramah:回答が更新されました。 –

    +0

    多くの感謝私はそれを試していないが、私は古いoneMany多くの感謝を修正した – Ramah

    0

    1)両方。すべてのデバイスをリッスンできるはずですが、リスナースレッドが以前に接続されたデバイスからのストリームを待っているため、コードではできないことがよくあります。

    2)おそらくそうではありません。 IIRC、NetworkStream.Readは、接続がピアデバイスによって閉じられると0を返します。これはあなたのプロトコルですか?デバイスが接続し、データを送信して切断しますか?もしそうなら、それはゆっくりと機能します。とにかく、別の問題があります。あなたのストリームで受け取ったバイトをデータに連結するだけでなく、読み返し(複数回)を1回の通信で複数回、おそらくは毎回1バイトでも(おそらくTCPストリームで許されます。あなたはバイト数rxを保持することができます。これまでは 'offset'パラメータを使用していました。

    3)リスニングスレッドは1つだけ必要です。 AcceptTcpClient()を呼び出すものこのスレッドは、AcceptTcpClient()によって返されたソケットからのデータを受信するための呼び出しをブロックするべきではありません。 AcceptTcpClient()によって返された各 'クライアント'ソケットに対してRead()ループを実行するか、非同期IOを使用するために、新しいクライアント/サーバスレッドを作成/割り当て/ depool /何でも作成します。

    4)NetworkStreamで待機している間に、新しいリスナー/読み取りスレッドが応答しなくなります。他のデバイスは接続できません。リスナーはすぐにAcceptTcpClient()に戻り、遅いネットワーク/デバイスがデータを送信するのを待つ必要がありません。

    RGDS、 マーティンあなたのコードで

    関連する問題