2017-01-13 57 views
0

我拿了https://netmq.readthedocs.io/上的一個簡單的接收/請求套接字示例,並希望使它在無限循環中與parametrizedThread一起工作。 代碼工作正常幾圈後,它拋出NetMQ接收/響應循環不工作

非阻塞套接字操作無法立即

完成了什麼,我得到了上面應該在第一循環結束後立即發生而不是隨機的。這裏有什麼問題?這聽起來像是必須刷新才能再次獲得乾淨的連接(不確定)。

class Program 
{ 
    public class Connector 
    { 
     public String connection { get; set; } 
     public ResponseSocket server { get; set; } 

     public Connector(string address, ResponseSocket server_) 
     { 
      this.connection = address; 
      this.server = server_; 
     } 
    } 

    static void Main(string[] args) 
    { 
     string connection = "tcp://localhost:5555"; 
     using (var server = new ResponseSocket()) 
     { 
      while (true) 
      { 
       try 
       { 
        server.Bind(connection); 
       } 
       catch (NetMQException e) 
       { 
        Console.WriteLine(e.ErrorCode); 
       } 

       Connector c = new Connector(connection, server); 

       ParameterizedThreadStart parametrizedClientThread = new ParameterizedThreadStart(runClientSide); 
       Thread t = new Thread(parametrizedClientThread); 
       t.Start(c); 
       //runClientSide(connection, server); 
      } 
     } 
    } 

    private static void runClientSide(object param) 
    { 
     Connector conn = (Connector)param; 
     string connection = conn.connection; 
     ResponseSocket server = conn.server; 
     using (var client = new RequestSocket()) 
     { 
      client.Connect(connection); 
      client.SendFrame("Hello"); 

      string fromClientMessage = server.ReceiveFrameString(); 
      Console.WriteLine("From Client: {0}", fromClientMessage); 
      server.SendFrame("Hi Back"); 

      string fromServerMessage = client.ReceiveFrameString(); 
      Console.WriteLine("From Server: {0}", fromServerMessage); 

      //Console.ReadLine(); 
     } 
    } 
+0

您只能使用相同的端口號打開一個到服務器的連接。您必須在打開新連接之前關閉連接,或者在每封郵件後都不要關閉連接。 while循環看起來不正確。 – jdweng

+0

不確定問題是否循環。事實上,如果你刪除了parametrizedThread部分並使用註釋掉的方法(修改下面的輸入參數),那麼代碼在循環中工作正常。對於我所知道的請求/響應不是線程安全的。不知道有什麼問題。 – yp10

+0

main()方法與跨線程的Thread不在同一進程中,並且需要使用「Invoke」在兩個進程之間傳輸數據。 – jdweng

回答

1

NetMQSockets不是線程安全的,而且您正在從客戶端線程內部訪問服務器以發送/接收數據。無論如何,客戶端不應該有權訪問服務器套接字。

首先將Bind移到while循環的外部,它只需要一次,而不是爲每個創建的客戶端。 要等待消息使用NetMQPoller,它將爲您處理其他所有事情,並在接收到消息後引發服務器ReceiveReady事件。

static void Main(string[] args) { 
    string connection = "tcp://localhost:5555"; 
    using (var poller = new NetMQPoller()) { 
     using (var server = new ResponseSocket()) { 
      server.ReceiveReady += Server_ReceiveReady; 
      poller.Add(server); 
      poller.RunAsync(); 

      server.Bind(connection); 

      // start 10000 clients 
      for(int i = 0; i < 10000; i++) { 

       ParameterizedThreadStart parametrizedClientThread = new ParameterizedThreadStart(runClientSide); 
       Thread t = new Thread(parametrizedClientThread); 
       t.Start(connection); 
      } 

      Console.ReadLine(); //let server run until user pressed Enter key 
     } 
    } 
} 

//server (e.Socket) is receiving data here and can answer it 
private static void Server_ReceiveReady(object sender, NetMQSocketEventArgs e) { 
    string fromClientMessage = e.Socket.ReceiveFrameString(); 
    Console.WriteLine("From Client: {0}", fromClientMessage); 
    e.Socket.SendFrame("Hi Back"); 
} 

private static void runClientSide(object param) { 
    string connection = (string) param; 

    using (var client = new RequestSocket()) { 
     client.Connect(connection); 
     client.SendFrame("Hello"); 

     //Removed server side code here and put it into ReceiveReady event 

     string fromServerMessage = client.ReceiveFrameString(); 
     Console.WriteLine("From Server: {0}", fromServerMessage); 
    } 
} 
+0

謝謝,我現在看到我做錯了。非常感謝幫助! – yp10