2013-05-08 54 views
0

我正在主应用程序运行一个C#服务器,我想将从服务器线程收到的消息传递给主线程。服务器应该在后台运行以获得新的连接。每次有新连接时,服务器都应该将收到的消息传递给主应用程序。如何让主应用知道何时收到消息?当有新连接时,如何将消息从服​​务器线程传递到主线程?从后台线程发送数据到主线程

主要应用

public partial class MainWindow : Window 
{ 
     TCPServer Server = new TCPServer(); //start running the server 
     //get the message (Server.message) when a client sent it to the server 
     //TODO process the message 
    } 

TCP服务器

class TCPServer 
    { 
     private TcpListener tcpListener; 
     private Thread listenThread; 
     private String message; 

     public TCPServer() 
    { 
     this.tcpListener = new TcpListener(IPAddress.Any, 3200); 
     this.listenThread = new Thread(new ThreadStart(ListenForClients)); 
     this.listenThread.Start(); 

    } 

//starts the tcp listener and accept connections 
    private void ListenForClients() 
    { 
     this.tcpListener.Start(); 

     while (true) 
     { 
      //blocks until a client has connected to the server 
      System.Diagnostics.Debug.WriteLine("Listening..."); 
      TcpClient client = this.tcpListener.AcceptTcpClient(); 
      System.Diagnostics.Debug.WriteLine("Client connected"); 


      //create a thread to handle communication 
      //with connected client 
      Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm)); 
      clientThread.Start(client); 
     } 
    } 


    //Read the data from the client 
    private void HandleClientComm(object client) 
    { 

     TcpClient tcpClient = (TcpClient)client; //start the client 
     NetworkStream clientStream = tcpClient.GetStream(); //get the stream of data for network access 

     byte[] message = new byte[4096]; 
     int bytesRead; 

     while (true) 
     { 
      bytesRead = 0; 

      try 
      { 
       //blocks until a client sends a message 
       bytesRead = clientStream.Read(message, 0, 4096); 
      } 
      catch 
      { 
       //a socket error has occured 
       break; 
      } 

      if (bytesRead == 0) //if we receive 0 bytes 
      { 
       //the client has disconnected from the server 


      break; 
       } 
       //message has successfully been received 
       ASCIIEncoding encoder = new ASCIIEncoding(); 
       message = encoder.GetString(message, 0, bytesRead); 

       //Reply 
       byte[] buffer = encoder.GetBytes("ACK"); 
       clientStream.Write(buffer, 0, buffer.Length); 
       System.Diagnostics.Debug.WriteLine("ACK"); 
       clientStream.Flush(); 
       } 
      tcpClient.Close(); 
      System.Diagnostics.Debug.WriteLine("Client disconnected"); 
     } 
+3

这是一个多处理器的应用程序吗? – 2013-05-08 23:21:03

+3

这是威胁**,而不是“威胁”。 – didierc 2013-05-08 23:23:45

+0

有主服务器,然后服务器应该在后台运行新线程。 – nabrugir 2013-05-08 23:35:43

回答

1

这是已经很好地支持的TcpListener,使用BeginAcceptTcpClient()方法来代替。当你从WPF或Winforms应用程序的主线程调用它时,回调将自动在同一主线程上运行。这同样适用于它的BeginReceive()方法。在内部,它使用调度程序循环来获取激活的回调方法,这与BackgroundWorker和C#v5 async/await关键字类的工作方式非常相似。

这可以让您免受起始终止麻烦,终止您自己的线程并确保您的编组正确回退。并大大减少您的程序的资源使用情况。强烈推荐。

+0

你的意思是从WPF运行TcpListener并避免使用TCPServer类?或者用TCPListener创建一个新类?任何参考或示例都会有所帮助。 – nabrugir 2013-05-09 00:00:17

0

队列就是答案。具体在这种情况下,一个Concurrent Queue

您的套接字线程将消息放入队列中。您的工作线程轮询队列并取出工作项目。

对于基于套接字的应用程序,这种模式非常非常常见。

或者,您可以针对系统线程池QueueUserWorkItem,并让它管理工作负载。

注意:您现在处于多线程状态。你需要阅读关于同步和其他将出现的问题。不这样做意味着你的应用程序将有非常奇怪的错误。

相关问题