C# 多线程服务器提供;无法访问已处置的对象";多个客户端尝试连接时出错
我有一个名为server.cs的多线程服务器和一个client.cs。该程序的目标如下: 每个客户端程序将创建到服务器的连接。 服务器将回复一条欢迎消息(字符串)。 客户端将向服务器发送json格式的字符串。 服务器将以相同的格式回复,但添加了有关机密和机密的信息 结束状态。然后,客户端将向服务器发送消息以停止 通讯,并将关闭连接。 当所有客户都进行了沟通后,最终会有一个客户 id=-1,通知服务器停止。当服务器收到消息时 从结束客户端(id=-1),它必须打印所有收集的信息和 沟通客户的数量 这是最重要的部分。当我在client.cs中使用C# 多线程服务器提供;无法访问已处置的对象";多个客户端尝试连接时出错,c#,multithreading,client-server,C#,Multithreading,Client Server,我有一个名为server.cs的多线程服务器和一个client.cs。该程序的目标如下: 每个客户端程序将创建到服务器的连接。 服务器将回复一条欢迎消息(字符串)。 客户端将向服务器发送json格式的字符串。 服务器将以相同的格式回复,但添加了有关机密和机密的信息 结束状态。然后,客户端将向服务器发送消息以停止 通讯,并将关闭连接。 当所有客户都进行了沟通后,最终会有一个客户 id=-1,通知服务器停止。当服务器收到消息时 从结束客户端(id=-1),它必须打印所有收集的信息和 沟通客户的数量
SequentialSimulation()
方法并运行client.cs程序的多个实例时,服务器工作正常,并按照上述描述执行。但是,当我在client.cs中使用ConcurrentSimulation()
方法,并且只运行clients.cs的一个实例时,它会崩溃,并给出以下错误:
Unhandled exception. System.AggregateException: One or more errors occurred. (Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.)
---> System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.Socket'.
at System.Net.Sockets.Socket.get_RemoteEndPoint()
at SocketClient.Client.endCommunication() in /Users/test/Documents/client/Program.cs:line 143
at SocketClient.ClientsSimulator.SequentialSimulation() in /Users/test/Documents/client/Program.cs:line 174
at SocketClient.ClientsSimulator.<ConcurrentSimulation>b__5_0() in /Users/test/Documents/client/Program.cs:line 191
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at SocketClient.ClientsSimulator.ConcurrentSimulation() in /Users/test/Documents/client/Program.cs:line 197
at SocketClient.Program.Main(String[] args) in /Users/test/Documents/client/Program.cs:line 219
client.cs:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Threading;
namespace SocketClient
{
public class ClientInfo
{
public string studentnr { get; set; }
public string classname { get; set; }
public int clientid { get; set; }
public string teamname { get; set; }
public string ip { get; set; }
public string secret { get; set; }
public string status { get; set; }
}
public class Message
{
public const string welcome = "WELCOME";
public const string stopCommunication = "COMC-STOP";
public const string statusEnd = "STAT-STOP";
public const string secret = "SECRET";
}
public class Client
{
public Socket clientSocket;
private ClientInfo info;
public IPEndPoint localEndPoint;
public IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
public readonly int portNumber = 11111;
public readonly int minWaitingTime = 50, maxWaitingTime = 100;
public int waitingTime = 0;
string baseStdNumber = "0700";
private String msgToSend;
public Client(bool finishing, int n)
{
waitingTime = new Random().Next(minWaitingTime, maxWaitingTime);
info = new ClientInfo();
info.classname = " INF2X ";
info.studentnr = this.baseStdNumber + n.ToString();
info.ip = "127.0.0.1";
info.clientid = finishing ? -1 : 1;
}
public string getClientInfo()
{
return JsonSerializer.Serialize<ClientInfo>(info);
}
public void prepareClient()
{
try
{
// Establish the remote endpoint for the socket.
localEndPoint = new IPEndPoint(ipAddress, portNumber);
// Creation TCP/IP Socket using
clientSocket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
}
catch (Exception e)
{
Console.Out.WriteLine("[Client] Preparation failed: {0}", e.Message);
}
}
public string processMessage(string msg)
{
Console.WriteLine("[Client] from Server -> {0}", msg);
string replyMsg = "";
try
{
switch (msg)
{
case Message.welcome:
replyMsg = this.getClientInfo();
break;
default:
ClientInfo c = JsonSerializer.Deserialize<ClientInfo>(msg.ToString());
if (c.status == Message.statusEnd)
{
replyMsg = Message.stopCommunication;
}
break;
}
}
catch (Exception e)
{
Console.Out.WriteLine("[Client] processMessage {0}", e.Message);
}
return replyMsg;
}
public void startCommunication()
{
Console.Out.WriteLine("[Client] **************");
Thread.Sleep(waitingTime);
// Data buffer
byte[] messageReceived = new byte[1024];
int numBytes = 0;
String rcvdMsg = null;
Boolean stop = false;
string reply = "";
try
{
// Connect Socket to the remote endpoint
clientSocket.Connect(localEndPoint);
// print connected EndPoint information
Console.WriteLine("[Client] connected to -> {0} ", clientSocket.RemoteEndPoint.ToString());
while (!stop)
{
// Receive the messagge using the method Receive().
numBytes = clientSocket.Receive(messageReceived);
rcvdMsg = Encoding.ASCII.GetString(messageReceived, 0, numBytes);
reply = this.processMessage(rcvdMsg);
this.sendReply(reply);
if (reply.Equals(Message.stopCommunication))
{
stop = true;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void sendReply(string msg)
{
// Create the message to send
Console.Out.WriteLine("[Client] Message to be sent: {0}", msg);
byte[] messageSent = Encoding.ASCII.GetBytes(msg);
int byteSent = clientSocket.Send(messageSent);
}
public void endCommunication()
{
Console.Out.WriteLine("[Client] End of communication to -> {0} ", clientSocket.RemoteEndPoint.ToString());
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
public class ClientsSimulator
{
private int numberOfClients;
private Client[] clients;
public readonly int waitingTimeForStop = 2000;
public ClientsSimulator(int n, int t)
{
numberOfClients = n;
clients = new Client[numberOfClients];
for (int i = 0; i < numberOfClients; i++)
{
clients[i] = new Client(false, i);
}
}
public void SequentialSimulation()
{
while(true){
Console.Out.WriteLine("\n[ClientSimulator] Sequential simulator is going to start ...");
for (int i = 0; i < numberOfClients; i++)
{
clients[i].prepareClient();
clients[i].startCommunication();
clients[i].endCommunication();
}
Console.Out.WriteLine("\n[ClientSimulator] All clients finished with their communications ... ");
Thread.Sleep(waitingTimeForStop);
Client endClient = new Client(true, -1);
endClient.prepareClient();
endClient.startCommunication();
endClient.endCommunication();
}
}
public void ConcurrentSimulation()
{
Console.Out.WriteLine("[ClientSimulator] Concurrent simulator is going to start ...");
var t = Task.Run(() => SequentialSimulation() );
var t1 = Task.Run(() => SequentialSimulation() );
var t2 = Task.Run(() => SequentialSimulation() );
var t3 = Task.Run(() => SequentialSimulation() );
var t4= Task.Run(() => SequentialSimulation() );
var t5 = Task.Run(() => SequentialSimulation() );
t.Wait();
t1.Wait();
t2.Wait();
t3.Wait();
t4.Wait();
t5.Wait();
}
}
class Program
{
// Main Method
static void Main(string[] args)
{
Console.Clear();
int wt = 5000, nc = 20;
ClientsSimulator clientsSimulator = new ClientsSimulator(nc, wt);
//clientsSimulator.SequentialSimulation();
Thread.Sleep(wt);
// todo: Uncomment this, after finishing the method.
clientsSimulator.ConcurrentSimulation();
}
}
}
使用系统;
Net系统;
使用System.Net.Sockets;
使用系统文本;
使用System.Text.Json;
使用System.Threading.Tasks;
使用系统线程;
命名空间SocketClient
{
公共类ClientInfo
{
公共字符串studentnr{get;set;}
公共字符串类名{get;set;}
public int clientid{get;set;}
公共字符串teamname{get;set;}
公共字符串ip{get;set;}
公共字符串机密{get;set;}
公共字符串状态{get;set;}
}
公共类消息
{
public const string welcome=“welcome”;
public const string stopCommunication=“COMC-STOP”;
public const string statusEnd=“STAT-STOP”;
public const string secret=“secret”;
}
公共类客户端
{
公共套接字clientSocket;
私人客户信息;
公共IPEndPoint localEndPoint;
公共IPAddress IPAddress=IPAddress.Parse(“127.0.0.1”);
公共只读int端口号=11111;
public readonly int minWaitingTime=50,maxWaitingTime=100;
public int waitingTime=0;
字符串baseStdNumber=“0700”;
私有字符串msgToSend;
公共客户端(bool整理,int n)
{
waitingTime=new Random().Next(minWaitingTime,maxWaitingTime);
info=新ClientInfo();
info.classname=“INF2X”;
info.studentnr=this.baseStdNumber+n.ToString();
info.ip=“127.0.0.1”;
info.clientid=整理?-1:1;
}
公共字符串getClientInfo()
{
返回JsonSerializer.Serialize(信息);
}
public void prepareClient()
{
尝试
{
//为套接字建立远程端点。
localEndPoint=新的IPEndPoint(ipAddress,端口号);
//使用创建TCP/IP套接字
clientSocket=新套接字(ipAddress.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
}
捕获(例外e)
{
Console.Out.WriteLine(“[Client]准备失败:{0}”,e.Message);
}
}
公共字符串处理消息(字符串消息)
{
WriteLine(“[Client]来自服务器->{0}”,msg);
字符串replyMsg=“”;
尝试
{
开关(msg)
{
案例信息。欢迎:
replyMsg=this.getClientInfo();
打破
违约:
ClientInfo c=JsonSerializer.Deserialize(msg.ToString());
if(c.status==Message.statusEnd)
{
replyMsg=Message.stopCommunication;
}
打破
}
}
捕获(例外e)
{
Console.Out.WriteLine(“[Client]processMessage{0}”,e.Message);
}
返回replyMsg;
}
公共无效startCommunication()
{
Console.Out.WriteLine(“[客户端]****************”);
线程。睡眠(等待时间);
//数据缓冲区
字节[]messageReceived=新字节[1024];
int numBytes=0;
字符串rcvdMsg=null;
布尔停止=假;
字符串reply=“”;
尝试
{
//将套接字连接到远程端点
Connect(localEndPoint);
//打印连接的端点信息
WriteLine(“[Client]连接到->{0}”,clientSocket.RemoteEndPoint.ToString());
当(!停止)
{
//使用Receive()方法接收消息。
numBytes=clientSocket.Receive(messageReceived);
rcvdMsg=Encoding.ASCII.GetString(messageReceived,0,numBytes);
reply=this.processMessage(rcvdMsg);
这是sendReply(reply);
if(reply.Equals(Message.stopCommunication))
{
停止=真;
}
}
}
捕获(例外e)
{
控制台写入线(e.Message);
}
}
公共void sendReply(字符串msg)
{
//创建要发送的消息
Console.Out.WriteLine(“[Client]要发送的消息:{0}”,msg);
byte[]messageSent=Encoding.ASCII.GetBytes
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Threading;
namespace SocketClient
{
public class ClientInfo
{
public string studentnr { get; set; }
public string classname { get; set; }
public int clientid { get; set; }
public string teamname { get; set; }
public string ip { get; set; }
public string secret { get; set; }
public string status { get; set; }
}
public class Message
{
public const string welcome = "WELCOME";
public const string stopCommunication = "COMC-STOP";
public const string statusEnd = "STAT-STOP";
public const string secret = "SECRET";
}
public class Client
{
public Socket clientSocket;
private ClientInfo info;
public IPEndPoint localEndPoint;
public IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
public readonly int portNumber = 11111;
public readonly int minWaitingTime = 50, maxWaitingTime = 100;
public int waitingTime = 0;
string baseStdNumber = "0700";
private String msgToSend;
public Client(bool finishing, int n)
{
waitingTime = new Random().Next(minWaitingTime, maxWaitingTime);
info = new ClientInfo();
info.classname = " INF2X ";
info.studentnr = this.baseStdNumber + n.ToString();
info.ip = "127.0.0.1";
info.clientid = finishing ? -1 : 1;
}
public string getClientInfo()
{
return JsonSerializer.Serialize<ClientInfo>(info);
}
public void prepareClient()
{
try
{
// Establish the remote endpoint for the socket.
localEndPoint = new IPEndPoint(ipAddress, portNumber);
// Creation TCP/IP Socket using
clientSocket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
}
catch (Exception e)
{
Console.Out.WriteLine("[Client] Preparation failed: {0}", e.Message);
}
}
public string processMessage(string msg)
{
Console.WriteLine("[Client] from Server -> {0}", msg);
string replyMsg = "";
try
{
switch (msg)
{
case Message.welcome:
replyMsg = this.getClientInfo();
break;
default:
ClientInfo c = JsonSerializer.Deserialize<ClientInfo>(msg.ToString());
if (c.status == Message.statusEnd)
{
replyMsg = Message.stopCommunication;
}
break;
}
}
catch (Exception e)
{
Console.Out.WriteLine("[Client] processMessage {0}", e.Message);
}
return replyMsg;
}
public void startCommunication()
{
Console.Out.WriteLine("[Client] **************");
Thread.Sleep(waitingTime);
// Data buffer
byte[] messageReceived = new byte[1024];
int numBytes = 0;
String rcvdMsg = null;
Boolean stop = false;
string reply = "";
try
{
// Connect Socket to the remote endpoint
clientSocket.Connect(localEndPoint);
// print connected EndPoint information
Console.WriteLine("[Client] connected to -> {0} ", clientSocket.RemoteEndPoint.ToString());
while (!stop)
{
// Receive the messagge using the method Receive().
numBytes = clientSocket.Receive(messageReceived);
rcvdMsg = Encoding.ASCII.GetString(messageReceived, 0, numBytes);
reply = this.processMessage(rcvdMsg);
this.sendReply(reply);
if (reply.Equals(Message.stopCommunication))
{
stop = true;
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
public void sendReply(string msg)
{
// Create the message to send
Console.Out.WriteLine("[Client] Message to be sent: {0}", msg);
byte[] messageSent = Encoding.ASCII.GetBytes(msg);
int byteSent = clientSocket.Send(messageSent);
}
public void endCommunication()
{
Console.Out.WriteLine("[Client] End of communication to -> {0} ", clientSocket.RemoteEndPoint.ToString());
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
public class ClientsSimulator
{
private int numberOfClients;
private Client[] clients;
public readonly int waitingTimeForStop = 2000;
public ClientsSimulator(int n, int t)
{
numberOfClients = n;
clients = new Client[numberOfClients];
for (int i = 0; i < numberOfClients; i++)
{
clients[i] = new Client(false, i);
}
}
public void SequentialSimulation()
{
while(true){
Console.Out.WriteLine("\n[ClientSimulator] Sequential simulator is going to start ...");
for (int i = 0; i < numberOfClients; i++)
{
clients[i].prepareClient();
clients[i].startCommunication();
clients[i].endCommunication();
}
Console.Out.WriteLine("\n[ClientSimulator] All clients finished with their communications ... ");
Thread.Sleep(waitingTimeForStop);
Client endClient = new Client(true, -1);
endClient.prepareClient();
endClient.startCommunication();
endClient.endCommunication();
}
}
public void ConcurrentSimulation()
{
Console.Out.WriteLine("[ClientSimulator] Concurrent simulator is going to start ...");
var t = Task.Run(() => SequentialSimulation() );
var t1 = Task.Run(() => SequentialSimulation() );
var t2 = Task.Run(() => SequentialSimulation() );
var t3 = Task.Run(() => SequentialSimulation() );
var t4= Task.Run(() => SequentialSimulation() );
var t5 = Task.Run(() => SequentialSimulation() );
t.Wait();
t1.Wait();
t2.Wait();
t3.Wait();
t4.Wait();
t5.Wait();
}
}
class Program
{
// Main Method
static void Main(string[] args)
{
Console.Clear();
int wt = 5000, nc = 20;
ClientsSimulator clientsSimulator = new ClientsSimulator(nc, wt);
//clientsSimulator.SequentialSimulation();
Thread.Sleep(wt);
// todo: Uncomment this, after finishing the method.
clientsSimulator.ConcurrentSimulation();
}
}
}