//标识是什么类型的数据
THeadPick=Packed Record
  ID:Word;
end;
//用户信息
TUserInfo=Packed Record
  Nname:String[16];
  PassWord:String[16];
end;
//用户登录时发的包
TLogonPick=Packed Record
  HeadPick:THeadPick;
  UserInfo:TUserInfo;
end;
//传送文件时发的包
TFilePick=Packed Record
  HeadPick:THeadPick;
  FileInfo:Array[0..5000] of Char;  
end;客户端向服务器发了一个数据包 ,每个数据包都是头结构体和数据结构体两部分组成,要根据不同的
头结构体来确定是什么数据.就是说先要读出THeadPick这一部分.如果客户端发送了一个TLogonPick 包
procedure TTCPServerSocket_Obj.TCPServerExecute(AThread: TIdPeerThread);
var
  NewasHeadPick:THeadPick;
  NewUserInfo:TUserInfo;
begin中用
  AThread .Connection .ReadBuffer (NewasHeadPick,SizeOf (THeadPick));
读取后,读取用户信息
  AThread .Connection .ReadBuffer (NewUserInfo,SizeOf (TUserInfo));
时就不正确了.是不是每次执行AThread .Connection .ReadBuffer后将Socket缓冲区中的数据都删除了????--------------------------------------
如果是用
    AThread .Connection .Socket .Recv(NewasHeadPick,SizeOf (THeadPick));
读取后,读取用户信息
  AThread .Connection .ReadBuffer (NewUserInfo,SizeOf (TUserInfo));
就正确了.我的理解是AThread .Connection .Socket .Recv 执行时只是读取了NewasHeadPick后将Socket缓冲区中的NewasHeadPick
删除了,
而AThread .Connection .ReadBuffer读取后,将Socket缓冲区清空了.
如果Socket缓冲区中没有数据AThread .Connection .ReadBuffer就阻塞了.end;我对系统的Socket接收数据缓冲区在什么时候会全部清空,什么时候只清除读取了的数据,如果读取时缓冲区没有数据什么情况下
读操作直接返回,什么情况下会阻塞不是很清楚,哪位老大知道给讲一下吧.或者告诉一下在什么书上讲了.还有系统的Socket发送缓冲区也有类型的问题,也说一下吧.

解决方案 »

  1.   

    AThread .Connection .ReadBuffer (NewasHeadPick,SizeOf (THeadPick));
    读取后,读取用户信息
      AThread .Connection .ReadBuffer (NewUserInfo,SizeOf (TUserInfo));这样是没问题的。
    --------------------------------
    是不是每次执行AThread .Connection .ReadBuffer后将Socket缓冲区中的数据都删除了????
    是删除了。
    ------------------------------
    Indy控件都是基于阻塞式的,如果跟踪的话,会发现如果客户端没有数据时,程序就等停在AThread .Connection .ReadBuffer (NewasHeadPick,SizeOf (THeadPick));这一句
    就是说他一直等到取到相同长度的数据后才继续向下执行。
      

  2.   

    程序通过了.SOCKET有接收和发送两个缓冲区,Indy控件都是基于阻塞式的,和UNIX的实现方式一样,如果收不到指定的长度就会停住直到缓冲区中有这个数据为止,每次读取数据的时候都是用MOVE的方式将SOCKET缓冲区的数据移走,如果读不完则会重新读.直到缓冲区为空时为止.现在服务器TIdTCPServer ,客户端用 TClientSocket,这两都的结合比都用INDY的好多了.