我有一个写入数据的TCP套接字列表。如果写入失败,我将其从列表中删除,然后继续。
至少这就是计划。发生的情况是,当客户端断开连接时,即使处理了该异常,SocketException也会升级并且程序崩溃。代码如下:
// sockets is type List<Socket>
foreach (Socket s in sockets)
{
String jsonString = skeleton.Marshall();
byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(jsonString);
try
{
s.Send(jsonBytes); // boom! System.Net.Sockets.SocketException!
}
catch (System.Net.Sockets.SocketException except)
{
sockets.Remove(s);
Console.WriteLine(except.StackTrace);
}
catch (Exception except)
{
Console.WriteLine(except.StackTrace);
}
}
我不明白为什么会有任何例外情况发生。我没有查看控制台输出,因为Visual Studio会在发生异常时清除(至少我没有看到任何有意义的内容)
感谢您的帮助!
正如Sebastian Negraszus指出的那样,我不能直接从列表中删除Socket,所以现在的代码是
List<Socket> remove = new List<Socket>();
// sockets still is of type List<Socket>
foreach (Socket s in sockets)
{
String jsonString = skeleton.Marshall();
byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(jsonString);
try
{
s.Send(jsonBytes);
}
catch (System.Net.Sockets.SocketException except)
{
remove.Add(s);
Console.WriteLine(except.StackTrace);
}
catch (Exception except)
{
Console.WriteLine(except.StackTrace);
}
}
foreach (Socket s in remove)
{
sockets.Remove(s);
}
但是,即使没有从列表中删除Socket,它也应该在这里升级。
此代码在事件处理程序中运行,而主要线程中正在填充套接字,因此我认为缺少锁定会导致问题。但是,添加锁后,错误仍然出现。
主线程:
// ...
sockets = new List<Socket>();
delegateFoo += handlerFunction;
// ...
TcpListener tcpListener = new TcpListener(IPAddress.Any, 20001);
tcpListener.Start();
while (true) {
Socket s = tcpListener.AcceptSocket();
lock (sockets) {
sockets.Add(s);
}
}
处理函数:
// ...generate skeleton...
lock (sockets)
{
foreach (Socket s in sockets)
{
String jsonString = skeleton.Marshall();
byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(jsonString);
try
{
s.Send(jsonBytes);
}
catch (System.Net.Sockets.SocketException except)
{
remove.Add(s);
Console.WriteLine(except.StackTrace);
}
catch (Exception except)
{
Console.WriteLine(except.StackTrace);
}
}
foreach (Socket s in remove)
{
sockets.Remove(s);
}
}
运气不好,Exception仍在升级(至少我认为是这样,程序在VS中断,这个小窗口发生了&#34; SocketException出现&#34;(我使用德语版本,所以措辞可能是不同)。 可以通过使用putty连接两次并关闭两个puttys中的一个来触发错误。下一次调用Send() - 繁荣。
抱歉,这些都是德语。文:
message =&#34;现有连接已被主机中止/终止&#34;
System.Net.Sockets.SocketException ist aufgetreten.
_HResult=-2147467259
_message=Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen
HResult=-2147467259
IsTransient=false
Message=Eine bestehende Verbindung wurde softwaregesteuert durch den Hostcomputer abgebrochen
Source=System
ErrorCode=10053
NativeErrorCode=10053
StackTrace:
bei System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
InnerException:
是的,我只在程序中发送一次()。
好的,它的Visual Studio很奇怪。我可以取消选中&#34;打破这种类型的例外&#34;复选框,然后它继续。因此,例外没有升级,但仍然使程序停止。
我不明白为什么你想要默认中断处理的异常。我想如果我取消选中该程序就会出错。如果您有更好的解决方案,我很乐意接受您的回答。
答案 0 :(得分:1)
我认为sockets
是List<T>
?仍然在sockets.Remove(s);
循环内部时,您无法使用foreach
修改列表,因为这会使枚举数无效。下一次迭代会导致InvalidOperationException
。
答案 1 :(得分:-1)
取消选中“此类异常中断”(或英语中的任何内容)。之后工作正常。