当前位置: 代码迷 >> C# >> tcpclient 报“由于目标计算机积极拒绝,无法连接”
  详细解决方案

tcpclient 报“由于目标计算机积极拒绝,无法连接”

热度:1011   发布时间:2016-05-05 05:20:31.0
求助 tcpclient 报“由于目标计算机积极拒绝,无法连接”
我的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捕获异常进行后续处理