我用这个线程是为了设备通讯的,线程在执行过程中要从设备中读取数据,如果设备中没有数据发送,线程会等待外设发送数据,可是如果这时候网络突然断开,线程是不会知道网络断开,线程一直在等待外设发送数据,可是外设已经断开,根本不会发送数据过来,这样这个线程就停到这了 。问题一:我是这样解决的,我在外面做了一个定时器,定时去检查设备状态,如果设备连接不到,我就想要重新启动刚才那个线程,可是线程正在运行,如何重启?问题二:如果我可以重启了,线程对应的方法是从方法的开始部分执行,还是从接收等待接收外设数据那开始,我之所以这么想是因为线程重启之前肯定是执行到这里。问题三:与外设通讯是网络通讯,TCP ,ip的,我想去判断我所连接的外设是否连接,我用tcpclient1..Connected来获取状态,可是当我直接吧网线拔下的时候,他的状态还是true,只有当我在连接一次tcpClient1.Connect(ip, Port);,我这个判断状态是在定时器里做的,如果定时去连接这个ip,那样是不是会多连接了无数次,程序开的时间越长,所开的连接就会越多,这样会影响到通讯的性能吧?
各位大侠,谁有好的办法帮我解决一下,小弟分不多,帮帮忙:我用这个线程是为了设备通讯的,线程在执行过程中要从设备中读取数据,如果设备中没有数据发送,线程会等待外设发送数据,可是如果这时候网络突然断开,线程是不会知道网络断开,线程一直在等待外设发送数据,可是外设已经断开,根本不会发送数据过来,这样这个线程就停到这了 。问题一:我是这样解决的,我在外面做了一个定时器,定时去检查设备状态,如果设备连接不到,我就想要重新启动刚才那个线程,可是线程正在运行,如何重启?问题二:如果我可以重启了,线程对应的方法是从方法的开始部分执行,还是从接收等待接收外设数据那开始,我之所以这么想是因为线程重启之前肯定是执行到这里。问题三:与外设通讯是网络通讯,TCP ,ip的,我想去判断我所连接的外设是否连接,我用tcpclient1..Connected来获取状态,可是当我直接吧网线拔下的时候,他的状态还是true,只有当我在连接一次tcpClient1.Connect(ip, Port);,我这个判断状态是在定时器里做的,如果定时去连接这个ip,那样是不是会多连接了无数次,程序开的时间越长,所开的连接就会越多,这样会影响到通讯的性能吧?
各位大侠,谁有好的办法帮我解决一下,小弟分不多,帮

解决方案 »

  1.   

    字好多,眼好累,只能给你up了。。你可以判断网卡断开时,把TCP连接释放了,网卡连接时,再连远程IP建立TCP,不用担心连接无数次,一个套接字端口只让你绑定一次的
      

  2.   

    貌似tcpclient如果有服务端突然断开。会抛异常。就可以停止线程。
    如果非要重启线程,就先终止再启动下。
      

  3.   

    我在详细说明一下,我的线程是通过tcpclient从外设读取数据,如果外设没有发送数据,他会在那等待,知道有数据了才继续执行,这应该是同步,可是就在等待外设发送数据的时候,我把网线突然断开,这时候线程仍然在等待接受,可是外设已经断开了,根本不会发送数据.所以我显示的状态仍然是连接,因为tcpcliect不知道网络已经断开了,为了解决这个问题,我用了一个timer,定时去触发来判断网络是否断开,可是我不能在timer中每次执行的时候都去连接这个ip,我要判断网络是否断开,如果断开了才去连接,我用tcpclient1..Connected来判断网络的状态,可是他的状态是true.
    原因我想可能是因为网络断开了而tcpclient不知道,只有从新连接的时候他才能判断网络的状态,如果我每次timer执行的时候都无条件的去连接这个ip,这样会不会抛弃原来的连接,如果抛弃的话,那么原来的连接如果正在接受数据,那数据肯定会丢失.
    我要从新连接的时候,一定是重新初始化线程,因为这个线程肯定是在接受数据的那个位置等待呢,如果我重新初始化线程,线程是从头开始执行还是从等待的接受数据的地方开始呢?
    先谢谢各位的帮助,无论是有用的还是没用的,我都要谢谢各位,小弟分不多,所以多谢各位的帮助!
      

  4.   

    我是菜鸟我也不很清楚,但是我感觉自己在学习某些板块,也是有类似的情况,最终都是发现自己学的不够细,光学了基本的,比如一个方法有很多重载版本,你都要去MSDN上看看,还有某些类的不太常用的方法,也许以后就用来,所以看看以后也好想起来复习.建议楼主是不是自己再努力下,看看自己哪里不足?
      

  5.   

    VB.net 或C#.net能够判断网络断开。
    C、C++不行。
    我的经验。
      

  6.   

    如果我在timer里 private void timer1_Tick(object sender, EventArgs e)
            {
                
                           string ElectronIp = ReadWriteIni.ReadCarRegister("ElectronEquipment", "Electron1Ip");
                string ElectronPort = ReadWriteIni.ReadCarRegister("ElectronEquipment", "Electron1Port");
                if (!CheckNetwork(ElectronIp, int.Parse(ElectronPort)))
                {
                  
                    receiveData1 = new Thread(new ThreadStart(receiveDT1Data));//用来接收读头数据的线程
                    receiveData1.IsBackground = true;
                    receiveData1.Start();
                }
            }
            private bool CheckNetwork(string hostName, int portNum)
            {
                try
                {
                    TcpClient client = new TcpClient(hostName, portNum);//如果能建立TCP连接,表示端口打开,否则,抛出异常
                    client.Close();
                    return true;
                }
                catch
                {
                    return false;
                }
            } private void timer1_Tick(object sender, EventArgs e)
            {
                
                           string ElectronIp = ReadWriteIni.ReadCarRegister("ElectronEquipment", "Electron1Ip");
                string ElectronPort = ReadWriteIni.ReadCarRegister("ElectronEquipment", "Electron1Port");
                if (!CheckNetwork(ElectronIp, int.Parse(ElectronPort)))
                {
                  
                    receiveData1 = new Thread(new ThreadStart(receiveDT1Data));//用来接收读头数据的线程
                    receiveData1.IsBackground = true;
                    receiveData1.Start();
                }
            }
            private bool CheckNetwork(string hostName, int portNum)
            {
                try
                {
                    TcpClient client = new TcpClient(hostName, portNum);//如果能建立TCP连接,表示端口打开,否则,抛出异常
                    client.Close();
                    return true;
                }
                catch
                {
                    return false;
                }
            }    
    这样的时候,网络网线拔掉以后,他会显示自动断开了,我插上的时候,他也会自动连接,可是刚连接不一会就会自动断开了,在等一会,会出错,说线程已经启动,无法再次启动
           public void receiveDT1Data()//接受数据
            {            string ElectronIp = ReadWriteIni.ReadCarRegister("ElectronEquipment", "Electron1Ip");
                
                string ElectronPort = ReadWriteIni.ReadCarRegister("ElectronEquipment", "Electron1Port");            try
                {
                    tcpClientDT1 = new TcpClient();
                    tcpClientDT1.Connect(ElectronIp, int.Parse(ElectronPort));
                    SetLabelText22("已连接");
                    SetLabel22Color(System.Drawing.Color.Chartreuse);
                    while (true)
                    {
                        ns1Data = tcpClientDT1.GetStream();
                        
                        stream1Reader = new StreamReader(ns1Data);
                        string tag = stream1Reader.ReadLine();
                       //这里是关于tag的处理
                     }
                }
                catch(Exception ex) 
                {
                    //MessageBox.Show(ex.Message);
                    //dt1Connection();
                    SetLabelText22("连接异常");
                    SetLabel22Color(System.Drawing.Color.Red);                Thread.Sleep(3000);//线程休眠,否则会引起方法的不执行,原因未知,主要导致读头不工作,连接成功,但不读取信息
                    receiveData1 = new Thread(new ThreadStart(receiveDT1Data));
                    receiveData1.IsBackground = true;
                    receiveData1.Start();
                }
            }
     这个方法是现成执行的方法,大家帮我分析下,看有什么问题
      

  7.   

    要判断网络是否连通, 不需要用 Connect, 定时发个空的数据过去就可以了, 要是网络中断了会抛出异常看了你的代码, 不是很能够理解为什么要那么频繁地 Connect。 我见过的网络同步通信程序都是开一条线程,新建一个 TCPClient 执行 TCPClinet.Connect 函数, 然后使用死循环重复利用这个 TCPClient 来 send 或者 Receive。 出现异常(通常是网络连接中断)是跳出死循环,线程就自然结束了。如要自动重连,在跳出死循环之后再从头开始做一次就是
      

  8.   

    楼上兄弟说的是,程序在接收的时候,就是这快 
                           stream1Reader = new StreamReader(ns1Data);
                        string tag = stream1Reader.ReadLine();
    线程在读取端口的时候,如果没数据的话,他会停在这,这时候如果网络断开了,是不会抛出异常的,他就在那傻等
    .我做的也是就一个开了一个线程.其实网络已经被我手动断开了,可是他不知道,异常不会抛出,所以这时候,我就想用一个timer 定时去判断网络是否断开了
      

  9.   

    问题一:如果检测到设备连接不到,就直接结束线程。
    问题二:新开一个线程,肯定是从开始部分执行啦。
    问题三:你只要定时Send一个检测字符过去就可以了,或者让客户端定时给你发送一个检测字符,FTP就是那样做的,由于FTP的控制命令连接是单独一个端口,所以客户端发送检测字符不会影响数据的接收。
      

  10.   


    TCP 协议是双向的, 读与写并不冲突。即使线程被阻塞在 string tag = stream1Reader.ReadLine(); 处, 你也可以再另外的线程中用同一个 TCPClient 发送数据啊, 不需要再开一个连接。定时发送检测用的空数据包就可以检测网络状况,要是发送出现异常了,直接就可以把 TCPClient 关掉重开。由于发送与接受是同一个 TCPClient, 代码还简单一些如果你有空去看看 MSDN 里面关于 Socket.send 与 Socket.Receive 的解释与例子,相信你的思路会清晰很多。(个人觉得 TCPClient 封装得太过漂亮了)
      

  11.   

    建议你换socket类,TCPClient封装之后带来很多不便
      

  12.   

    我刚开始做过一次向端口发送数据,可是即使网络断开了,我发送也不会出现异常,不知道什么事?
    也谢谢你的建议,我一会去看下msdn