TCP多个客户端一个服务器,发送序列化对象

时间:2014-05-11 11:52:58

标签: c# serialization tcp

我真的遇到了麻烦。我正在尝试构建一个连接多个客户端的服务器(保持连接打开),当它收到一个序列化对象时,它会将该对象发送回所有连接的客户端。到目前为止,我已经能够将对象发送到服务器并对服务器端进行反序列化,但是我无法将该对象发送回所有客户端。这是我到目前为止所得到的:

服务器代码:

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 个答案:

答案 0 :(得分:1)

您的问题是在读取服务器上的数据后断开套接字(通过调用NetworkStream.Close),从而无法广播(发送)人物对象。

删除客户端和服务器中对NetworkStream.Close的调用,您的代码将按预期工作。