所以当我在客户端断开连接时出现问题时,我正在制作Tcp服务器。异常被抛出,但看起来服务器看不到它。并且它不会从列表中删除断开连接的客户端。这是代码:
public void Read(IAsyncResult ar, TcpClient PL)
{
try
{
{
BytesRead[PL] = PL.GetStream().EndRead(ar);
}
if (BytesRead[PL] < 1)
{
throw new SocketException();
}
else
{
SplitRead[PL] += BytesRead[PL];
while (true)
{
if (SplitRead[PL] < 4)
{
break;
}
int num = BitConverter.ToInt16(readBuffer[PL], 2);
if (SplitRead[PL] < num)
{
break;
}
if (!Tlist.ContainsKey(PL))
Tlist.Add(PL, new List<RecvData>());
{
Tlist[PL].Add(new RecvData(readBuffer[PL], num));
}
int index = 0;
for (int i = num; i < SplitRead[PL]; i++)
{
readBuffer[PL][index] = readBuffer[PL][i];
index++;
}
SplitRead[PL] -= num;
}
}
}
catch (Exception x)
{
if ((x.Message.Contains("Client") && x.Message.Contains("Disconnected")) || x is SocketException || x is EndOfStreamException || x is IOException) //|| x.InnerException.GetType() == typeof(IOException))
{
clients.Remove(PL);
}
else
{
System.Console.WriteLine(x.ToString());
}
}
}
当客户端关闭程序或被任务管理器
杀死时,会发生这种情况这是使用方法Read
的地方。
private void HandleClient(object client)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream ns = tcpClient.GetStream();
AssemblyStuff assemblystuff = new AssemblyStuff();
while (true)
{
try
{
while ((true))
{
{
if (!ClientAuthComplete.ContainsKey(tcpClient))
ClientAuthComplete.Add(tcpClient, false);
if (!readBuffer.ContainsKey(tcpClient))
readBuffer.Add(tcpClient, new byte[102400]);
if (!SplitRead.ContainsKey(tcpClient))
SplitRead.Add(tcpClient, 0);
if (!BytesRead.ContainsKey(tcpClient))
BytesRead.Add(tcpClient, 0);
if (!Tlist.ContainsKey(tcpClient))
Tlist.Add(tcpClient, new List<RecvData>());
try
{
IAsyncResult result = ns.BeginRead(readBuffer[tcpClient], SplitRead[tcpClient], 30000, null, null);
Read(result, tcpClient);
}
catch (SocketException ex)
{
if ((ex.Message.Contains("Client") && ex.Message.Contains("Disconnected")) || ex is SocketException)
{
throw;
}
}
try
{
if (Tlist.ContainsKey(tcpClient))
{
if (Tlist[tcpClient].Count >= 1)
{
for (int i = 0; i < Tlist[tcpClient].Count; i++)
{
ReceiveData(Tlist[tcpClient][i].Buffer, Tlist[tcpClient][i].Len, tcpClient);
}
Tlist.Clear();
}
}
}
catch (Exception ex)
{
}
}
}
}
catch (SocketException ex)
{
if (((ex.Message.Contains("Client") && ex.Message.Contains("Disconnected"))) || ex is SocketException )
{
clients.Remove(tcpClient);
readBuffer.Remove(tcpClient);
SplitRead.Remove(tcpClient);
BytesRead.Remove(tcpClient);
Tlist.Remove(tcpClient);
threads[tcpClient].Abort();
threads.Remove(tcpClient);
ClientAuthComplete.Remove(tcpClient);
RemoveClientFromList(tcpClient);
}
else
{
System.Console.WriteLine(ex.ToString());
}
}
}
}
以下是TcpListener
初始化
public void Server1()
{
timer = new Timer(new TimerCallback(MultipleCheck), null, 0, 500);
listener = new TcpListener(IPAddress.Parse("25.75.22.56"), 29339);
listenThread = new Thread(new ThreadStart(ListenForClients));
listenThread.Start();
}
这是接受TcpClient
private void ListenForClients()
{
listener.Start();
while (true)
{
System.Console.Title = "Black3D Server : " + clients.Count.ToString();
if (!LineStarted)
{
System.Console.WriteLine("Server started on port 29339");
LineStarted = true;
}
System.Console.WriteLine("Connection Request");
TcpClient client = listener.AcceptTcpClient();
if (client.Connected)
{
clients.Add(client);
System.Console.WriteLine("New Client Connected");
if (!readBuffer.ContainsKey(client))
readBuffer.Add(client, new byte[102400]);
if (!SplitRead.ContainsKey(client))
SplitRead.Add(client, 0);
if (!BytesRead.ContainsKey(client))
BytesRead.Add(client, 0);
if (!Tlist.ContainsKey(client))
Tlist.Add(client, new List<RecvData>());
if (!threads.ContainsKey(client))
threads.Add(client, new Thread(new ParameterizedThreadStart(HandleClient)));
//if (threads.ContainsKey(client))
{
threads[client].Start(client);
}
counter++;
}
}
}
答案 0 :(得分:0)
在threads[tcpClient].Abort();
放置试用指令之前
try
{
//Removing Client from list and notifying connected users about disconnected
//client from list
}
catch
{
}
//And after Abort the thread to avoid the exception of thread aborting being
//thrown too early
threads[tcpClient].Abort();
threads.Remove(tcpClient);