把数据包sendstream方式发送出去。在数据头中包含有关数组的情况,如数据包大小,数组长度,数据类型等情况,接收方先接收数据头,根据数据头中的信息分配接收缓冲,接收数据。也可以先把数据头发送到接收方,在确认接收方已经准备好以后再发送数据。

解决方案 »

  1.   

    TO:二位大虾
    能具体的说一下么??假设要发送lv这个无符号整数2字节的数据。如何做
       谢谢大虾~~~
                                方便面敬上
      

  2.   

    发送方
    procedure TForm1.Button1Click(Sender: TObject);
    Const
     nArrayLenth =1000;
    var
      AWords :array[0..nArrayLenth] of word;
      Num :integer;
    begin
      Num :=nArrayLenth;
    ....
            ....   
      ClientSocket1.Socket.SendBuf(Num,sizeof(Integer));       //发送数组长度
      ClientSocket1.Socket.SendBuf(Awords[0],Num*sizeof(Word));//发送数组
    end;
    接收方
    ...
    ...var
     RevArrays:array of Word;
     nReseived,nRevSize,nStep: integer;
     RevStream :TMemoryStream;...
    ...
    //初始化
    procedure TForm1.FormCreate(Sender: TObject);
    begin
       nStep :=0;
       RevStream :=Tmemorystream.Create;
    end;
    ...
    ...
    //接收
    procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    var
     Buf :pointer;
     nCount,nRevBytes :integer;
    begin
     Case  nStep of
      0 : begin  //数据头
             socket.ReceiveBuf(nCount,sizeof(Integer));
             Setlength(RevArrays,nCount);
             nRevSize :=nCount*Sizeof(Word);
             RevStream.Clear;
             RevStream.Position :=0;
             nReseived :=0;
             Inc(nStep);
          end;
      1: begin //接收数据
             Getmem(Buf,Socket.ReceiveLength);
             nRevBytes :=Socket.ReceiveBuf(Buf^,Socket.ReceiveLength);
             nReseived :=nReseived+nRevBytes;
             RevStream.Write(Buf^,nRevBytes);
             Freemem(buf);
             if nReseived>=nRevSize then
             begin
                nStep :=0;
                RevStream.Position:=0;
                RevStream.Readbuffer(RevArrays[0],RevStream.size);
                ....//对接受数据进行处理
             end;
         end;
      end;end;
      

  3.   

    和我做的项目一样,没必要做成SendStream那么复杂,凡是用到数据流Stream的都复杂化。
    const
       SOCKET_LEN=1024//包的最大长度
    THead=record
       Len:word;
       CmnCode:longword;
       Content:array[0..139] of byte;
      end;
    TSocketPKT=record
        Head:THead;
        body:array[0..SOCKET_LEN-1] of byte;
      end;procedure TfrmSocket.csConfRead(Sender: TObject; Socket: TCustomWinSocket);
    var
      i, len, pktlen : Integer;
      pkt : TSocketPkt;
      bSom : Boolean;
      InBuf : array [0..SOCKET_LEN - 1] of Byte;
      ptrInBuf : Integer;
    begin
      ptrInBuf := 0;
      bSom := True;
      while true do
      begin
        if bSom then
        begin
          i := Socket.ReceiveBuf(InBuf[ptrInBuf], SOCKET_LEN - ptrInBuf);
          if i > 0 then ptrInBuf := ptrInBuf + i;
        end;
        if ptrInbuf <= 0 then exit;    len := GetSockLen(@InBuf, ptrInBuf);
        if len = -1 then
        begin
          Socket.Close;
          Exit;
        end;
        FillChar(pkt, SizeOf(pkt), 0);
        pktlen := SocketDecode(@InBuf, @pkt, len);    if (pktlen <> 0) and (pktlen >= ntohs(pkt.h.CmdLen) + 2) then
        begin
          if len < ptrInBuf then move(InBuf[len], InBuf, ptrInbuf - len);
          ptrInBuf := ptrInBuf - len;
          case ntohs(pkt.h.CmdCode) of
            HLTH_CHK_RESP : doHealthCheckResp(pkt);
            NMA_GET_RESP : doGetResp(pkt);
            NMA_SET_RESP : doSetResp(pkt);
    {            ADM_ALM : DealAlm(Socket, pkt);
            ADM_RECONFIG_RESP : DealReconfigresp(pkt, Socket);
            ADM_GMSC_CURRENT_RESP : DealGmscResp(pkt, Socket);
            ADM_TUP_CURRENT_RESP : DealTupResp(pkt, Socket);
            ADM_TUP_CIC_RESP : DealCicResp(pkt, Socket);
            ADM_DEV_STATUS_RESP: DealDevResp(pkt, Socket);
            ADM_DEV_ALERT : DealDevAlert(pkt, Socket);
            else DisplayAlm('Local', '901', '5', DatetimeToStr(Now),
                         Socket.RemoteAddress+ ' Socket receive unknown CmdId');}
          end;
          ErrorFlag := False;
        end
        else
        begin
          if ErrorFlag then
          begin
            move(InBuf[len], InBuf, ptrInbuf - len);
            ptrInBuf := ptrInBuf - len;
            ErrorFlag := False;
          end
          else
          begin
            ErrorFlag := True;
            Exit;
          end;
        end;    if Socket.ReceiveLength > 0 then Exit;
        bSom := False;
      end;
    end;procedure TfrmSocket.doHealthCheckResp(pkt : TSocketPkt);
    begin
      HealthCheckNoRespCount := 0;
      if g_IsDebug then
      begin
        lblHealthCheckResp.Caption := DateTimeToStr(Now);
        ShowPkt(ntohs(pkt.h.CmdLen)+ 2, @pkt, mmoHealthCheckResp);
      end;
    end;   end;
      

  4.   

    自己调用sendto api函数即可