流程二是很常见的阻塞方式SOCKET程序线程使用方式.

解决方案 »

  1.   

    客户断开时socket会返回一个错误,你可以用getlasterrro获取.
    对于第一个问题,同意楼上的看法.
      

  2.   

    TO menliwxj(有缘)
    能不能告诉错误代号呢?
      

  3.   

    你的两个流程里似乎都只有一个线程在工作看你的流程,你用的应该是基于连接的TCP1是重叠服务器处理方式
    (重叠服务器的特点是占用资源少,但是效率教低,客户等待时间可能会比较长)
     (处理用户命令必须是不用耗时太多的操作,如果操作太耗时间,请选用并发处理方式)2是并发服务器处理方式
    (并发服务器的特点于重叠服务器相反)需要说明的是1中创建线程可以创建一个线程,处理连接,处理命令,
    再处理连接的一个循环过程。
    2中的创建线程则是一个连接来到就创建一个线程处理命令,并且2的整个流程
    还要放到一个线程中。
      

  4.   

    你可以将帮定socket放在线程外,其它放在线程内.
      因为你是基于Tcp的,所以你可在一定时间范围内看服务端的发到客户端的信息有无返回,如没有,则表示客户端已断开.
      

  5.   

    同意sosomybaby的说法,同时,我认为阻塞方式更安全,如果是非堵塞方式,很可能会丢包。
      

  6.   

    sosomybaby(baby) 不合理的处理。
    以下为我测试是否有断开连接程序。请大家看一看。哪里需要改动的。
    暂时还没有还没有实现。为什么不行呢?
    而且客户端没有一点提示。
    ///server
    var
      ca:sockaddr_in;
      binderr,calen:integer;
      acceptskt:Tsocket;
      buf:array of byte;
    begin
      if trim(edit1.Text)='' then exit;
      server:=socket(AF_INET,SOCK_STREAM,0);
      if server=invalid_socket then
      begin
        messagebox(handle,'创建套间字出错。','系统提示',mb_ok);
        exit;
      end;
      zeromemory(@ca,sizeof(sockaddr_in));
      ca.sin_port:=htons(strtoint(trim(edit1.text)));
      ca.sin_family:=af_inet;
      calen:=sizeof(sockaddr_in);  binderr:=bind(server,ca,calen);
      if binderr<>0 then
      begin
        messagebox(handle,'绑定套间字出错。','系统提示',mb_ok);
        closesocket(server);
        exit;
      end;
      listen(server,8);
      messagebox(handle,'服务器正处开启状态。','系统提示',mb_ok);
      isrun:=true;
      while isrun do
      begin
        acceptskt:=accept(server,@ca,@calen);
        if acceptskt<>invalid_socket then
        begin
            setlength(buf,1);
            recv(acceptskt,buf[0],1,0);
            if buf[0]=$A then
            begin
                send(acceptskt,buf[0],1,0);
                closesocket(acceptskt);
                break;
            end;
        end;
      end;
      closesocket(server);
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      clientsocket1.Port:=634;
      clientsocket1.Address:='192.168.0.25';
      clientsocket1.Open;
    end;
    客户程序用组件测试的。
    procedure TForm1.ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    var
        buf:array of byte;
    begin
        setlength(buf,1);
        buf[0]:=$A;
      socket.SendBuf(buf[0],1);
    end;procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    begin
        showmessage('disconnect');
    end;procedure TForm1.ClientSocket1Read(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      buf:array of byte;
      len:integer;
    begin
      len:=socket.ReceiveLength;
      setlength(buf,len);
      socket.ReceiveBuf(buf[0],len);
      if buf[0]=$A then
        showmessage('OK'); 
    end;procedure TForm1.ClientSocket1Error(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    begin
      showmessage('error');
    end;
      

  7.   

    所谓重叠服务器是:
      接收连接->处理请求->断开连接
        |                  |
         -------------------
    那么[处理请求]过程中,无法再处理完请求之前响应第二个连接并发服务器是:
       接收连接->创建命令线程
         |           |
          -----------  
    处理请求由命令处理线程完成,也就是例如,一个写大文件的“处理请求”
    对于重叠服务而言,文件写完之前,其他任何人无法连接到服务器。对于并发服务而言,文件写操作在命令处理线程之内,无论它完成于否,
    系统一样可以接收连接,处理请求。因此多个客户可以同时操作,所以叫并发服务器!