2011-07-11 86 views
2

我有一個GPS設備,將安裝在許多卡車。 我可以配置設備通過gprs發送數據語句「gps data,device id」到IP和端口。 我使用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. 我需要爲每個設備配置不同的端口併爲每個設備端口創建一個新的監聽線程嗎?

  4. 有時我面對異常「請求信道超時,同時等待答覆」對您有所幫助

許多在此先感謝。

回答

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

錯誤\t \t 1爲「System.Threading.ThreadPool.QueueUserWorkItem(的System.Threading最好重載方法匹配。WaitCallback)'有一些無效的參數,另一個錯誤Error2Argument'1':無法從'無效'轉換爲'System.Threading.WaitCallback' – Ramah

+0

@ Ramah:答案已更新。 –

+0

非常感謝我沒有嘗試它,但我固定舊one.many很多謝謝 – Ramah

0

1)Both。您應該能夠監聽所有設備,但是由於監聽器線程正在等待來自之前連接的設備的流,因此您通常無法使用代碼。

2)可能不是。 IIRC,當對等設備關閉連接時,NetworkStream.Read返回0。這是你的協議 - 即。設備連接,發送一些數據並斷開連接?如果這樣的話會起作用,儘管很慢。無論如何,還有另一個問題。你應該將流上接收到的字節連接到數據,而不僅僅是替換它們。Read()我多次返回一次通信,甚至每次只有一個字節(不太可能,但是允許TCP流)。你可以保留字節數rx。到目前爲止,並使用'偏移'參數來做到這一點。

3)你只需要一個監聽線程,即。調用AcceptTcpClient()的那個。此線程不應使阻塞調用從AcceptTcpClient()返回的套接字接收數據。無論是創建/分配/解包/無論新的客戶端服務器線程爲AcceptTcpClient()返回的每個「客戶端」套接字運行Read()循環,還是使用異步IO。

4)當您在NetworkStream上等待時,您的單個偵聽器/讀取線程將無法響應新連接 - 其他設備將無法連接。監聽器應該快速返回AcceptTcpClient(),而不是等待慢速網絡/設備發送數據。

RGDS, 馬丁

相關問題