我真的遇到了麻烦。我正在尝试构建一个连接多个客户端的服务器(保持连接打开),当它收到一个序列化对象时,它会将该对象发送回所有连接的客户端。到目前为止,我已经能够将对象发送到服务器并对服务器端进行反序列化,但是我无法将该对象发送回所有客户端。这是我到目前为止所得到的:
服务器代码:
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();
}
}
}
如果有人可以帮我解决这个问题,我会非常感激。
答案 0 :(得分:1)
您的问题是在读取服务器上的数据后断开套接字(通过调用NetworkStream.Close
),从而无法广播(发送)人物对象。
删除客户端和服务器中对NetworkStream.Close
的调用,您的代码将按预期工作。