2012-02-25 5 views
6

Trong Delphi XE2 Tôi có một loại kỷ lục với cấu trúc sau:Gửi và Nhận Stream với TidTCPClient và TIdTCPServer trong Delphi XE2

TMachinInfoRec = record 
    IPStr: string[15]; 
    Username: string[50]; 
    Computername: string[100]; 
    SentTime: TDateTime; 
    HasCommand: integer; 
    ClientCommands: array[0..9] of TMachineCommand; 
    end; 

tôi định nghĩa một biến trên biến TMemoryStream và ở phía Client và gửi dòng với TidTCPClient thành phần:

var 
    MIRec: TMachinInfoRec; 
    msRecInfo: TMemoryStream; 

begin 
    MIRec.IPStr = '192.168.100.101'; 
    MIRec.Username := 'user-a'; 
    MIRec.Computername := 'Computer-a'; 
    MIRec.SentTime := Now(); 

    idTCPClient.Host := '192.168.100.138'; 
    idTCPClient.Port := 6000; 

    idTCPClient.Connect; 

    msRecInfo := TMemoryStream.Create; 
    msRecInfo.Write(msRecInfo, SizeOf(Client)); 

    msRecInfo.Position := 0; 
    idTCPClient.IOHandler.Write(msRecInfo); 
end; 

và và có được thông tin về phía máy chủ với TIdTCPServer:

procedure TFrmMainServer.TCPServerExecute(AContext: TIdContext); 
var 
    MIRec: TMachinInfoRec; 
    msRecInfo: TMemoryStream; 
begin 
    msRecInfo:= TMemoryStream.Create; 

    AContext.Connection.IOHandler.ReadStream(msRecInfo, SizeOf(MIRec)); 

    msRecInfo.Read(msRecInfo, sizeOf(MIRec)); 

    ShowMessage(MIRec.IPStr); 
    ShowMessage(MIRec.Computername) 
end; 

Nhưng một chuỗi được hiển thị theo định dạng này:

MZ? ......... yy .., ....... @ ......... .........................., ....

làm cách nào tôi có thể giải quyết vấn đề này?

+1

Khi di chuyển cấu trúc kỷ lục giữa các quá trình khác nhau hoặc trong quá trình I/O, tuyên bố kỷ lục với 'chỉ thị packed'. Nếu không, có thể có sự cố liên kết. Tôi không nói đây là trường hợp ở đây, nhưng nó có thể là một lỗi tiềm năng sau này. –

+6

Đừng quên thiết lập lại 'Vị trí' của luồng về 0 sau khi gọi' ReadStream() 'và trước khi gọi' Read() '. Ngoài ra, hãy sử dụng 'TIdMemoryBufferStream' thay vì' TMemoryStream' để cho Indy đọc/ghi các biến bản ghi của bạn trực tiếp. –

Trả lời

7

nên không

 msRecInfo.Write(msRecInfo, SizeOf(Client)); 

được

 msRecInfo.Write(miRec, SizeOf(miRec)); 

Same để đọc:

 msRecInfo.Read(miRec, sizeOf(MIRec)); 

Lưu ý rằng có một số yếu tố không chắc chắn khác với mã này:

  • "khách hàng" là gì? OTOH, với các sửa đổi ở trên, điều này được loại bỏ.
  • Chúng tôi không thể xác nhận từ mã này mà TMachineCommand không phải là một loại con trỏ