我的client端每秒发送一个指令给server端,然后接收server端的数据。程序正常执行300个循环后,报错:
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
Additional information: 由于目标计算机积极拒绝,无法连接。
下面是我的代码:
public void Poll()
{
foreach (var station in stations)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPollCallback), COMMStates[station.Id]);
}
if (WaitHandle.WaitAll(COMMStates.Select(p => p.Value.Completed).ToArray(), millsecondsTimeout, false))
{
}
else
{
Console.WriteLine("timeout");
foreach (var cs in COMMStates)
{
if (cs.Value != null)
{
cs.Value.Abort();
}
}
}
}
public void ThreadPollCallback(object state)
{
var cs = state as COMMState;
if (cs == null) return;
var station = cs.Station;
using (TcpClient tc = new TcpClient(station.IP, 3100)) //在这里报错
{
try
{
Console.WriteLine("comm thread start");
if (cs.Aborted)
{
Console.WriteLine("comm thread abort");
try
{
tc.GetStream().Close();
}
catch
{
}
try { tc.Close(); }
catch { }
}
else
{
COMMIpMaster master = COMMIpMaster.CreateIp(tc);
var length = master.ReadWaveLength();//这里就是一个write,一个read
if (length % 24 != 0)
{
throw new Exception("长度不正确");
}
ushort[] res = master.ReadWaveData((ushort)length);//这里就是一个write,一个read
lock (lockObj)
{
Data[station.Id] = new List<ushort>(res);
stationErrNum[station.Id] = 0;
Exceptions[station.Id] = null;
}
}
}
catch (Exception e)
{
Console.WriteLine("comm thread error");
lock (lockObj)
{
Exceptions[station.Id] = e;
stationErrNum[station.Id]++;
if (stationErrNum[station.Id] > 3)
{
Data[station.Id] = new List<ushort>(12); ;
}
}
}
finally
{
cs.Completed.Set();
}
}
}
public class COMMState
{
public Station Station;
public volatile Thread Thread;
public readonly ManualResetEvent Completed = new ManualResetEvent(false);
public volatile Exception Exception;
public volatile bool Aborted;
public void Abort()
{
if (!Aborted)
{
Aborted = true;
try { Thread.Abort(); }
catch { }
}
}
}
------解决思路----------------------
既然是tcp链接,你又为什么要搞那么碎的链接?tcp就是用来搞可靠性的长链接的。碎片化的短暂链接考虑一下udp协议。
不知道你server的实现,可能端口用完了,或者对于短时间内重复访问有限制等等。不论如何,每秒一次重复性链接用tcp协议肯定是不合适的
------解决思路----------------------
不要乱用Thread.Abort(),可能会导致线程还没有释放连接,你就把它强制结束掉了
你应该设置超时时间,如果超时就抛异常,然后你用try,catch捕获异常进行后续处理