大家好,目前我碰到个棘手的问题,用TIDTCPServer写了一个程序,原理很简单,就是CLIENT 连接到SERVER ,我用的是INDY 9的TIDTCPServer 控件,每次连接上来都是触发OnExecute事件后起一个线程由我程序中进行逻辑处理,现在碰到一个比较头疼的问题,就是因为SOCKET本身是无法知道对方有没有断线,所以如果TIDTCPServer是基于SOCKET话那DISCONNECT其实是只能表示"我已经断开但我仍接收数据"的状态等待握手,我的问题来了:比如说我同一IP作为CLIENT机器第一次正常连接上SERVER后由于网络中断而无法发送DISCONNECT的消息给SERVER,此时SERVER其实是不知道他已经断开,然后我CLIENT有一个TIMER事件就是当断开后会自动重新连接到SERVER,这个时候第2次连上去后,我在SERVER中是用程序去强制DISCONNECT中断前面那个未处理的第一个connection,结果DISCONNECT一做之后,我发现居然第2个连接也无法正常通信了,为了查问题,我检查过CLIENT发起的2个连接是不同的端口,按照我以前用其他语言编写程序的经验来看应该是不会有这样的情况2个其实是独立的连接,是不是INDY控件问题还是什么设置不对,我DELPHI不是很熟,不知道什么原因,请哪位高手帮我指点迷津,谢谢了,分数不够可以加

解决方案 »

  1.   

    补充一下,我在程序中自己写了一个connection manager的结构体我把每次登陆的IP和端口都是记录下来的所以我可以保证我第2次上来连接强制断掉的肯定是第一个未处理连接
      

  2.   

    再补充一下,断开第一个连接后第2个连接就会抛异常"connection reset by peer"居然复位了,晕啊
      

  3.   

    我就是直接 Athread.connection.disconnect 请问一般是怎么写的?
      

  4.   

    在测试过程中我发现好象主要CLIENT有DISCONNECT动作先而且网络通常的情况下SERVER的DISCONNECT是正常的,就是CLIENT网络不好的情况下,SERVER主动DISCONNECT时会发生该情况
      

  5.   

    SERVER,应该知道client断开啊!你下载一个indy demo看看嘛!
    里面有IdTCPDemo,感觉Client.Disconnect;会向服务端发送一个断开命令!
    不管是不是,反正Server能检查Client断开!
      

  6.   

    第一,当客户端重复登陆后是可以断开第一次登陆连接的,这点是可以做到的而且没有问题,那么肯定是你代码处理方面有问题,你可以查一下,也可以这样做,当发现重复登陆后断开第一次连接,也断开第二次连接。第二,先定义一个数据结构,再在事件Connect(AThread: TIdPeerThread)中加入如下代码:
    type            //心跳数据包结构
      TCP_KeepAlive = record
        OnOff: Cardinal;
        KeepAliveTime: Cardinal;
        KeepAliveInterval: Cardinal;
      end;
    .....
    var
      iVal: TCP_KeepAlive;
    ....
      iVal.OnOff:=1;
      iVal.KeepAliveTime:=5000;
      iVal.KeepAliveInterval:=5000;
      WSAIoctl(AThread.Connection.Socket.Binding.Handle, IOC_IN or IOC_VENDOR or 4,
        @iVal, SizeOf(iVal), nil, 0, @iRet, nil, nil);客户端断开后5秒后服务端就可以知道了。
      

  7.   

    补充:引用,WinSock2,哈哈,怕你不知道。
      

  8.   

    大家不要误导新人一般情况客户端断开连接与否,不用特别考虑,你可以一直按照定好的协议收数据,发现收到的数据长度不是你要的你就可以认为连接断开了(是可以认为,不是肯定)。如果客户端和服务段进行长连接,互相不是连续发数据,那就扩充协议,没数据发就互相经常发些无用的垃圾包(心跳),可以避免两边的read不超时,代码逻辑也可以简单些。你可以看看一些常用的ftp客户端软件,里面经常发送的pwd之类的命令就是保持连接用的。iRet = thread.connection.readbuffer(buffer, iNeed);
    //如果客户端没有断开那么数据不够时就会堵塞在这儿,不可能if iRet < iNeed then exit;//这就是断开了,如果是客户端主动断开,这里一般就是返回0长度,异常断开可能有点垃圾数//....继续处理......