Type
  SendData=packed record
    Command:string[5];
    Content:string[255];  //不用数组服务器读不到,加上又不能完全发送,而且最大只能255
  end;
如何修改?我的做法如下
Type
  SendData=packed record
    Command:string[5];
    Content:array[0..1024] of char;
  end;var SendData:TSendData;
begin
  FillChar(SendData,SizeOf(SendData),0);
  StrPCopy(@SendData.Command,'send');
  StrPCopy(@SendData.Content,EdtMsg.Text);
  IdTcpClient.WriteBuffer(SendData,SizeOf(SendData),True);
end;服务器端这样取
  ShowMessage(StrPas(@SendData.Content));其他的答案大家分享下,比如使用PChar,Byte本人抛砖引玉,大家踊跃发言哈,这问题原来也困扰了偶好久哈^_^

解决方案 »

  1.   

    有这样的问题?是不是最新的Indy10啊?
      

  2.   

    不会吧,我这样用,Data不限长度的吧
    procedure TAsyncTCPClient.Write(const Data: String);
    var
      FLen: Cardinal;
    begin
      FLen := Length(Data);
      if Connected and (FLen > 0) then
      try
        inherited;
        FIOHandler.WriteBufferOpen;
        FIOHandler.Write(PACKET_SIG);
        FIOHandler.Write(FLen);
        FIOHandler.Write(Data);
        FIOHandler.WriteBufferFlush;
      except on E: Exception do
        DoClose(E);
      end;
    end;
    读取:
        FCode := FIOHandler.ReadSmallInt();
        if FCode = PACKET_SIG then
        begin
          FLen := FIOHandler.ReadLongWord();
          if FLen > 0 then
            Result := FIOHandler.ReadString(FLen);
        
          if Length(Result) > 0 then
            LogMessage('Receive: ' + Result);
      

  3.   

    IdTcpClient,字符
      

  4.   

    一般网络通信中不使用string,带长string的结构体,里面只是一个地址,没意义,段string又有长度限制。而已第一个元素还是长度,不一定有意义。
    所以用char,byte都行,Pchar存在跟长string一样的问题,根本不用考虑。
      

  5.   

    一般网络通信中不使用string,带长string的结构体,里面只是一个地址,没意义,段string又有长度限制。而已第一个元素还是长度,不一定有意义。
    所以用char,byte都行,Pchar存在跟长string一样的问题,根本不用考虑。
      

  6.   

    一般网络通信中不使用string,带长string的结构体,里面只是一个地址,没意义,段string又有长度限制。而已第一个元素还是长度,不一定有意义。
    所以用char,byte都行,Pchar存在跟长string一样的问题,根本不用考虑。
      

  7.   

    //不用数组服务器读不到,加上又不能完全发送,而且最大只能255 
    不用数组时传过去的是这边的地址,你让服务器上的string访问他自己的地址就不知道是啥玩意了。
      

  8.   

    Type 
      SendData=packed record 
        Command: array[0..5] of char;
        Content:array[0..1024] of char; 
      end; 
    应该是STRING的问题。
      

  9.   

    楼主没有弄明白一个问题:
    String[N],实际上是一个ShortString,它就只支持256个字节(含结束符在内)。
    A ShortString is 0 to 255 characters long. While the length of a ShortString can change dynamically, its memory is a statically allocated 256 bytes; the first byte stores the length of the string, and the remaining 255 bytes are available for characters. If S is a ShortString variable, Ord(S[0]), like Length(S), returns the length of S; assigning a value to S[0], like calling SetLength, changes the length of S. ShortString is maintained for backward compatibility only. The Delphi language supports short-string types - in effect, subtypes of ShortString - whose maximum length is anywhere from 0 to 255 characters. These are denoted by a bracketed numeral appended to the reserved word string. For example, var MyString: string[100];
    creates a variable called MyString whose maximum length is 100 characters. This is equivalent to the declarations type CString = string[100];
    var MyString: CString;
    Variables declared in this way allocate only as much memory as the type requires - that is, the specified maximum length plus one byte. In our example, MyString uses 101 bytes, as compared to 256 bytes for a variable of the predefined ShortString type. When you assign a value to a short-string variable, the string is truncated if it exceeds the maximum length for the type. The standard functions High and Low operate on short-string type identifiers and variables. High returns the maximum length of the short-string type, while Low returns zero.
      

  10.   

    对于无限大小的数据,可以定义如下的结构(操作起来应该还是相对比较方便的)
    Type
      PSendData = ^TSendData;
      TSendData = packed record 
        Command:string[5]; 
        Content_len: Integer;
        Content:[0..0] of AnsiChar;  
      end; 
    对于这个结构,看似Content只有一个字节,实际上当你采用动态分配的时候,它就可以有N(包括0)个字节。只是需要关闭编译器的越界检查。发送端var
      Data: PSendData;
      strContent: String;//注意:这里只说ANSI Code,如果是使用Unicode版本(Delphi2009)的,另议
    begin
      strContent := ... //这里数据任意
      GetMem(Data, sizeof(TSendData) - 1 (*默认的一个字节*) + Length(strContent));
      Data^.Command := 'Text';
      Data^.Content_len := Length(strContent);
      Move(strContent[1], Data^.Content[0], Length(strContent));
      SendData(Data);
      FreeMem(Data);
    end;接收端var
      Data: PSendData;
    begin
      AllocMem(Data, sizeof(TSendData) - 1 (*默认的一个字节*) );
      RecvData(Data, sizeof(TSendData) - 1 (*默认的一个字节*) );
      if Data^.Content_len > 0 then begin
        ReallocMem(Data, sizeof(TSendData) - 1 (*默认的一个字节*) + Data^.Content_len);
        RecvData(@(Data^.Content[0]),  Data^.Content_len);
      end;
      ProcessCommand(Data);
      FreeMem(Data);
    end;
      

  11.   

    下面是我用的数据包结构
      TPackageRec = record
        Checker: integer;  // 4 bytes 包起始标志
        PackSize: integer;  // 4 bytes 包尺寸
        SerialNo: integer;   // 4 bytes 包序号
        case integer of
          0: // Command Package;
            ( prCommand: Byte;  // 1 bytes
              PackType: Byte;   // 1 bytes 包类型
              WantAnswer: ByteBool;   // 1 bytes 是否需要应答
              CheckSum: Byte;   // 1 byte 包校验
              Parami: array [0..3] of integer;  // 整型参数
              Params: array[0..1023] of Char; // 数据
            );
          1: // Status Package;
            ( prStatus: Byte;
            );
          2: // ptData
            ( prData: Byte;
            );
      end;
      PPackageRec = ^TPackageRec;
    实际包数据不一定有1024字节,有多少算多少。
      

  12.   

    socket的缓存好像本来就必须是一个buffer的
    基本是数组的char或byte
      

  13.   

    ////////////////////////
    Type 
      SendData=packed record 
        Command:string[5]; 
        Content:string[255];  //不用数组服务器读不到,加上又不能完全发送,而且最大只能255 
      end; 
    如何修改? 
    //////////////////////
    可以不用数组,但是这个结构就只有2个指针,所以发送的时候不能一次发送出去。
    Type 
      SendData=packed record 
        Command:string; 
        Content:string;   
      end; 
    var SendData:TSendData; 
    begin 
      SendData.Command:='send'; 
      SendData.Content:=EdtMsg.Text); 
      IdTcpClient.WriteBuffer(Pointer(@SendData.Command[1])^,Length(SendData.Command),True); 
      IdTcpClient.WriteBuffer(Pointer(@SendData.Content[1])^,Length(SendData.Content),True); 
    end; 接收端也要分别接收,或者一次全部接收到一个buffer中,分别赋值给command和content
      

  14.   

    type
      a1=packed record
       s1:string[100]
    end
    var
      pa:array of a1;
    begin
      setLength(pa,sizeof(a1)*1000);
      end;
      
      

  15.   

    扩展下15楼的数据结构使用方法:Type
      PSendData = ^TSendData;
      TSendData = packed record 
        Command:string[5]; 
        Content_len: Integer;
        Content:[0..0] of AnsiChar;  
      end; 由于Content只有一个字节,那么使用的时候要特别注意,可以GetMem一个足够大的空间,准备给这个数组溢出来使用。
    不过弊端在于如果定义使用了类似 sdTmp:TSendData;那么sdTmp.Content的拷贝操作会溢出,导致覆盖sdTmp变量后面的数据空间,
    从而程序异常,而这样的异常现象千奇百怪,很难调试,所以千万注意。使用中也可以不动态申请空间,用个固定的缓冲区来强制转换,可以把buf定义为全局变量,减少内存的申请以及释放。
        buf:Array[0..Max_packet_len] of Char;
    ..........
        Data:PSendData;.................
        Data:=PSendData(@buf[0]);
        Move(strContent[1], Data^.Content[0], Length(strContent));
        IdTcpClient.WriteBuffer(pChar(@buf[0])^,len,True);
    ...........
      

  16.   

    可以采用分包的方法来解决,有时间可以www.itstudy.net 去看看,收集了很多开发文章
      

  17.   

    type 
      SendData = record
        Command  :char[5];
        Content  :array[1..255] of char;
      end;//发送
    var
      MySendData: SendData;
      Buffer: array[1..1024] of char;
    begin
      CopyMemory(@Buffer[1],@MySendData,SizeOf(MySendData));
      IdTcpClient.Socket.Send(Buffer,SizeOf(MySendData));
    end;
    //读取var
      MyReadData: SendData;
    begin
      AThrea.ReadBuffer(MyReadData,SizeOf(MyReadData));
    //...就可以处理了MyReadData.Command  定长的还是比较简单的,关键是
    type 
      SendData = record
        MyList: TList;    //....麻烦了,在研究中
      end;
      

  18.   

    var
      LoginTime: Integer;
      CBLogin: TCBLogin;
      Buffer: array[1..2048] of Char;
    BEGINCopyMemory(@Buffer[1], @CBLogin, SizeOf(CBLogin)); //buffer2开始写内容
      ClientTCP.Socket.Send(Buffer, SizeOf(CBLogin));
    END;