C# 多线程服务器提供;无法访问已处置的对象";多个客户端尝试连接时出错

C# 多线程服务器提供;无法访问已处置的对象";多个客户端尝试连接时出错,c#,multithreading,client-server,C#,Multithreading,Client Server,我有一个名为server.cs的多线程服务器和一个client.cs。该程序的目标如下: 每个客户端程序将创建到服务器的连接。 服务器将回复一条欢迎消息(字符串)。 客户端将向服务器发送json格式的字符串。 服务器将以相同的格式回复,但添加了有关机密和机密的信息 结束状态。然后,客户端将向服务器发送消息以停止 通讯,并将关闭连接。 当所有客户都进行了沟通后,最终会有一个客户 id=-1,通知服务器停止。当服务器收到消息时 从结束客户端(id=-1),它必须打印所有收集的信息和 沟通客户的数量

我有一个名为server.cs的多线程服务器和一个client.cs。该程序的目标如下:

每个客户端程序将创建到服务器的连接。 服务器将回复一条欢迎消息(字符串)。 客户端将向服务器发送json格式的字符串。 服务器将以相同的格式回复,但添加了有关机密和机密的信息 结束状态。然后,客户端将向服务器发送消息以停止 通讯,并将关闭连接。 当所有客户都进行了沟通后,最终会有一个客户 id=-1,通知服务器停止。当服务器收到消息时 从结束客户端(id=-1),它必须打印所有收集的信息和 沟通客户的数量

这是最重要的部分。当我在client.cs中使用
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();

        }
    }
}