2014-05-11 77 views
-1

我真的遇到了這個問題。我試圖建立一個連接多個客戶端的服務器(保持連接打開),當它接收到一個序列化的對象時,它將把這個對象發回給所有連接的客戶端。到目前爲止,我已經能夠將對象發送到服務器並將它們反序列化到服務器端,但我無法將該對象發送回所有客戶端。下面是我到目前爲止有:TCP多個客戶端一臺服務器,發送序列化對象

Server代碼:

using System; 
using System.Collections; 
using System.Collections.Generic; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 

namespace Multi_Threaded_TCP 
{ 
    class TcpServer 
    { 
     private TcpListener _server; 
     private Boolean _isRunning; 

     private List<TcpClient> connectedClients = new List<TcpClient>(); 

     public TcpServer(int port) 
     { 
      _server = new TcpListener(IPAddress.Any, port); 
      _server.Start(); 
      Console.Write("Server running..."); 
      _isRunning = true; 
      LoopClients(); 
     } 

     public void LoopClients() 
     { 
      while (_isRunning) 
      { 
       // wait for client connection 
       //Add the client to the connected clients list 
       TcpClient newClient = _server.AcceptTcpClient(); 
       connectedClients.Add(newClient); 
       // client found. 
       // create a thread to handle communication 
       Thread t = new Thread(new ParameterizedThreadStart(HandleClient)); 
       t.Start(newClient); 
      } 
     } 

     public void HandleClient(object obj) 
     { 
      // retrieve client from parameter passed to thread 
      TcpClient client = (TcpClient)obj; 
      // sets two streams 
      StreamWriter sWriter = new StreamWriter(client.GetStream(), Encoding.ASCII); 
      StreamReader sReader = new StreamReader(client.GetStream(), Encoding.ASCII); 
      // you could use the NetworkStream to read and write, 
      // but there is no forcing flush, even when requested 
      Boolean bClientConnected = true; 
      while (bClientConnected) 
      { 
        //Deserialize into Person object 
       try 
       { 
        Person p = null; 
        if (!client.Connected) 
         return; 
        NetworkStream strm = client.GetStream(); 
        IFormatter formatter = new BinaryFormatter(); 
        p = (Person)formatter.Deserialize(strm); // you have to cast the deserialized object 
        strm.Close(); 
        Console.WriteLine("Person's first name: " + p.FirstName); 
        //Send the object back out to all connected clients 
        foreach (TcpClient t in connectedClients) 
        { 
         try 
         { 
           TcpClient tt = t; 
           //tt = new TcpClient(); 
           //tt.Connect(ipAddress1, portNum1); 
           IFormatter formatter1 = new BinaryFormatter(); // the formatter that will serialize my object on my stream 
           NetworkStream strm1 = tt.GetStream(); // the stream 
           formatter1.Serialize(strm1, p); // the serialization process 
           strm1.Close(); 
         } 
         catch 
         { 
         } 
        } 
       } 
       catch { } 
       } 

       } 
      } 
     } 

客戶端代碼:

using System; 
using System.Collections.Generic; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 
using System.Runtime.Serialization; 
using System.Runtime.Serialization.Formatters.Binary; 

namespace Client 
{ 
    class ClientDemo 
    { 
     private TcpClient _client; 
     private Boolean _isConnected; 
     private string ipAddress1; 
     private int portNum1; 

     public ClientDemo(String ipAddress, int portNum) 
     { 
      ipAddress1 = ipAddress; 
      portNum1 = portNum; 
      _client = new TcpClient(); 
      _client.Connect(ipAddress, portNum); 
      Thread HandleCom = new Thread(HandleCommunication); 
      HandleCom.Start(); 
     } 

     public void HandleCommunication() 
     { 
      connectedClients.Add(_client); 
      _isConnected = true; 
      Person p = null; 
      while (_isConnected) 
      { 
       try 
       { 
        //if (_client.GetStream().DataAvailable == false) 
         //return; 
        //System.Windows.Forms.MessageBox.Show("Data available!"); 
        //Need to check if theres any data in the object 
        //System.Windows.Forms.MessageBox.Show(_client.GetStream().DataAvailable.ToString()); 
        //System.Windows.Forms.MessageBox.Show(""); 
        NetworkStream strm = _client.GetStream(); 
        IFormatter formatter = new BinaryFormatter(); 
        p = (Person)formatter.Deserialize(strm); // you have to cast the deserialized object 
        //strm.Close(); 
        if (p != null) 
         System.Windows.Forms.MessageBox.Show(p.FirstName); 
       } 
       catch 
       { 
        //System.Windows.Forms.MessageBox.Show(ex.Message); 
       } 
      } 
     } 

     public void SendData(Person data) 
     { 
      if (!_client.Connected) 
      { 
       _client = new TcpClient(); 
       _client.Connect(ipAddress1, portNum1); 
      } 
      IFormatter formatter = new BinaryFormatter(); // the formatter that will serialize my object on my stream 
      NetworkStream strm = _client.GetStream(); // the stream 
      formatter.Serialize(strm, data); // the serialization process 
      strm.Close(); 
     } 
    } 
} 

如果有人可以幫助我想出解決辦法,我會非常感激。

回答

1

您的問題是,在讀取服務器上的數據後無法廣播(發送)person對象,從而斷開套接字(通過調用NetworkStream.Close)。

在客戶端和服務器中刪除對NetworkStream.Close的調用,並且您的代碼將按預期工作。

相關問題