请高手指点一下,我用TClientSocket和TServerSocket编写的程序,当TClientSocket连续(大概有1000-2000条记录左右,一次连续就要发这么多)向TServerSocket发送数据(数据库里的一些记录)时,发了一点(大概100-200条)后就发不出去了!请问是怎么回事?先谢谢大家!

解决方案 »

  1.   

    推荐使用idtcpclient,和idtcpserver来搞...
      

  2.   

    ChinaOk(授人以鱼,不如授人以渔)你好:
      我不熟悉idtcpclient,和idtcpserver啊,你有这方面的例子吗?
      

  3.   

    可以先写到内存流里,用SendStream发送。
      

  4.   

    是不是你Client端在处理发过来的数据
    把缓存给填满了之后,Sever端发来的数据丢掉了?
      

  5.   

    在Client端建个缓冲,然后用一个单独的线程处理缓冲里的数据
      

  6.   

    wolf2005你好:
      可以说清楚点吗?我不明白!你例子吗?我的E_MAIL:[email protected]给我一份源码,好吗?先谢谢你了!一定给分!
      

  7.   

    wolf2005你好:
      你说:“在Client端建个缓冲,然后用一个单独的线程处理缓冲里的数据”具体怎么建缓冲呀?你例子吗?我的E_MAIL:[email protected]给我一份源码,好吗?先谢谢你了!一定给分!
      

  8.   

    代码一时找不到,说一思路希望能解决你的问题
    1、建立接收区(InofmationList:TStrings 在Form或DataModule的Creat里要先创建好)
    procedure TDMSocket.AMClientSocketRead(Sender: TObject;
      Socket: TCustomWinSocket);
    begin
        InofmationList.Add(Socket.ReceiveText);
        ProcessData;//处理线程
    end;2、ProcessData;//处理线程
    while InofmationList.Count>0
      begin
        取出第一条处理,处理完了,清除掉第一条
      end;
    大体思路就这样
      

  9.   

    wolf2005你好:
      这样应该可以,但是,我发送的记录是很个字段的,12个字段,都是字符串的(除了1个字段外)分解时很麻烦哟!你有没有简单的办法来分解它们呀!请你说说思路好吗?我的QQ : 21673300 你在网上吗?你的QQ可以给我吗?
      

  10.   

    不好意思,我们这里不能上QQ
    你可以用这里短信。
    在Sever端发送的时候,你可先在把字段值用豆号分开如:'name,old,12,er45k,232'把这个作为一个记录发到Client端。以豆号作为分隔符分解就可以了pos,copy,等函数分解
      

  11.   

    hzxswfj(hzxswfj) 你好
      你说:“你可以采用应答的模式,处理数据”,可以说得更具体一些吗,我不太明白,具体怎样做!谢谢!
      

  12.   

    你是使用阻塞方式还是非阻塞方式SOCKET?从发送端看,你发送的时候判断返回值,如果是阻塞方式,发成功多少字节返回值就是多少
    ,然后你接着发剩下的。如果是非阻塞方式,是写到缓存,返回失败你就这次全部重发。
      

  13.   

    另外,TClientSocket的SendStream里面这些判断都做了的,处理得还行,你可以用它,或者
    参考它的源码。
      

  14.   

    halfdream(哈欠) 你好
      我是采用的 ctNonBlocking 模式 ,请问一下, 你说的“如果是非阻塞方式,是写到缓存,返回失败你就这次全部重发。”是重发这条记录吗?   “...写到缓存...”的具体原理是什么,你可以给我讲一下吗?先谢谢!你是这面的例子吗?给我一份好吗?我的 E_MAIl : [email protected] !  你有ctBlocking模式的例子,请给我一份好吗? 我的QQ是 21673300, 我常在线,你可以用QQ给我讲一下吗?万分感谢!
      

  15.   

    int readn(SOCKET fd, char *vptr, int n)
    {
    int nleft;
    int nread;
    char *ptr;

    ptr = vptr;
    nleft = n;

    while(nleft>0)
    {
    if( (nread = ::recv(fd, (char *)ptr, nleft, 0)) <0 )
    {
    if(nread == SOCKET_ERROR)
    return -1;
    }
    else if(nread ==0)
    {
    break;        //EOF
    }

    nleft -= nread;
    ptr += nread;
    }

    return (n-nleft);
    }//Write "n" bytes to a descriptor
    int writen(SOCKET fd, const char *vptr, int n)
    {
    int nleft;
    int nwritten;
    const char *ptr;

    ptr = vptr;
    nleft = n;
    while(nleft>0)
    {
    if( (nwritten = ::send(fd, ptr, nleft, 0)) <= 0)
    {
    if(nwritten == SOCKET_ERROR)
    return -1;
    }
    nleft -= nwritten;
    ptr += nwritten;
    }

    return n;
    }
      

  16.   

    楼主,叫你看看SendStream的代码你怎么不看呢?
    这可是捷径,让你明白把数据可靠的发出去。。看懂再用,
    别盲目抄.
    //----ScktComp.pas------------
    function TCustomWinSocket.SendStreamPiece: Boolean;
    var
      Buffer: array[0..4095] of Byte;
      StartPos: Integer;
      AmountInBuf: Integer;
      AmountSent: Integer;
      ErrorCode: Integer;begin
      Lock;//锁定,为多线程安全
      try
        Result := False;
        if FSendStream <> nil then
        begin
          if (FSocket = INVALID_SOCKET) or (not FConnected) then exit;
          while True do
          begin
            StartPos := FSendStream.Position;
            AmountInBuf := FSendStream.Read(Buffer, SizeOf(Buffer));
            if AmountInBuf > 0 then
            begin
              AmountSent := send(FSocket, Buffer, AmountInBuf, 0);//AmountSent是发送出去的字节数.
              if AmountSent = SOCKET_ERROR then
              begin
                ErrorCode := WSAGetLastError;
                if ErrorCode <> WSAEWOULDBLOCK then
                begin
                  Error(Self, eeSend, ErrorCode);
                  Disconnect(FSocket);
                  DropStream;
                  if FAsyncStyles <> [] then Abort;
                  Break;
                end else //WSAEWOULDBLOCK异常则让下次循环再发
                begin 
                  FSendStream.Position := StartPos;
                  Break;
                end;
              end else if AmountInBuf > AmountSent then
                FSendStream.Position := StartPos + AmountSent
              else if FSendStream.Position = FSendStream.Size then
              begin
                DropStream;
                Break;
              end;
            end else
            begin
              DropStream;
              Break;
            end;
          end;
          Result := True;
        end;
      finally
        Unlock;//解除锁定..
      end;
    end;
      

  17.   

    你使用SendBuf的时候返回值要作必要判断.//非阻塞方式处理注意:
    For non-blocking sockets, the data is sent to the WinSock DLL which has it's own internal buffers. If the WinSock can accept additional data, SendBuf returns immediately with the number of bytes queued. If the WinSock internal buffer space is not able to accept the buffer being sent, SendBuf returns -1 and no data is queued at all. In this case, wait a bit for the WinSock to have a chance to send out already-queued data; then try again.//阻塞方式处理:
    For blocking sockets, SendBuf returns the number of bytes actually written. 如果你用的是SENDTEXT,它实际是调用了SendBuf
    function TCustomWinSocket.SendText(const s: string): Integer;
    begin
      Result := SendBuf(Pointer(S)^, Length(S));
    end;