Delphi TidTCPServer和TidTCPClient传输记录
我需要帮助来了解如何通过Indy TCP服务器/客户端传输记录.我有两个程序,我把客户端和另一个服务器.
在客户端上我按下了一个按钮:客户端是TIdTCPClient Client.Connect(); 在服务器端,我在ServerConnect事件上添加一行到客户端连接的备忘录 Protocol.Lines.Add(TimeToStr(Time)+' connected '); 要从客户端发送数据,我有一条记录,我想发送: Tmyrecord = record IPStr: string[15]; end; 我在那里有一个发送按钮: procedure Tform1.ButtonSendClick(Sender: TObject); var MIRec: Tmyrecord; msRecInfo: TMemoryStream; begin MIRec.IPStr := '172.0.0.1'; msRecInfo := TMemoryStream.Create; msRecInfo.Write(MIRec,SizeOf(MIRec)); msRecInfo.Position := 0; Client.IOHandler.Write(msRecInfo); end; 在服务器端onexecute我有以下代码,我在服务器端也声明了相同的tmyrecord: procedure TServerFrmMain.ServerExecute(AContext: TIdContext); var MIRec: Tmyrecord; msRecInfo: TMemoryStream; begin if AContext.Connection.Connected then begin AContext.Connection.IOHandler.CheckForDataOnSource(10); if not AContext.Connection.IOHandler.InputBufferIsEmpty then begin msRecInfo:= TMemoryStream.Create; AContext.Connection.IOHandler.ReadStream(msRecInfo); msRecInfo.Read(MIRec,sizeOf(msRecInfo)); ShowMessage(MIRec.IPStr); end; end; end 我不知道为什么它不起作用,为什么我不能显示我从客户端写的IP地址. 非常感谢提前 解决方法
您正在犯一个经典的新手错误 – 您期望TIdIOHandler.Write(TStream)和TIdIOHandler.ReadStream()方法的默认行为相互匹配,但它们实际上并不相同.
TIdIOHandler.ReadStream()的默认参数值告诉它期望Integer或Int64(取决于TIdIOHandler.LargeStream属性的值)在流数据之前指定数据的长度. 但是,TIdIOHandler.Write(TStream)的默认参数值不会告诉它发送任何此类Integer / Int64值.因此,您使用TIdIOHandler.ReadStream()读取记录的前几个字节并将它们解释为Integer / Int64(给定您发送的字符串值为926036233),然后等待那么多字节到达,从来没有这样TIdIOHandler.ReadStream()不会退出(除非您将TIdIOHandler.ReadTimeout属性设置为非无限值). 您的代码中还有一些其他小错误/拼写错误,它们使用Indy之外的TMemoryStream对象. 试试这个: procedure Tform1.ButtonSendClick(Sender: TObject); var MIRec: Tmyrecord; msRecInfo: TMemoryStream; begin MIRec.IPStr := '172.0.0.1'; msRecInfo := TMemoryStream.Create; try msRecInfo.Write(MIRec,SizeOf(MIRec)); // writes the stream size then writes the stream data Client.IOHandler.Write(msRecInfo,True); finally msRecInfo.Free; end; end; procedure TServerFrmMain.ServerExecute(AContext: TIdContext); var MIRec: Tmyrecord; msRecInfo: TMemoryStream; begin msRecInfo := TMemoryStream.Create; try // reads the stream size then reads the stream data AContext.Connection.IOHandler.ReadStream(msRecInfo,-1,False); msRecInfo.Position := 0; msRecInfo.Read(MIRec,SizeOf(MIRec)); ... finally msRecInfo.Free; end; end; 或这个: procedure Tform1.ButtonSendClick(Sender: TObject); var MIRec: Tmyrecord; msRecInfo: TMemoryStream; begin MIRec.IPStr := '172.0.0.1'; msRecInfo := TMemoryStream.Create; try msRecInfo.Write(MIRec,SizeOf(MIRec)); // does not write the stream size,just the stream data Client.IOHandler.Write(msRecInfo,False); finally msRecInfo.Free; end; end; procedure TServerFrmMain.ServerExecute(AContext: TIdContext); var MIRec: Tmyrecord; msRecInfo: TMemoryStream; begin msRecInfo := TMemoryStream.Create; try // does not read the stream size,just the stream data AContext.Connection.IOHandler.ReadStream(msRecInfo,SizeOf(MIRec),False); msRecInfo.Position := 0; msRecInfo.Read(MIRec,SizeOf(MIRec)); ... finally msRecInfo.Free; end; end; 或者,您可以使用TIdBytes而不是TStream发送记录: procedure Tform1.ButtonSendClick(Sender: TObject); var MIRec: Tmyrecord; Buffer: TIdBytes; begin MIRec.IPStr := '172.0.0.1'; Buffer := RawToBytes(MIRec,SizeOf(MIRec)); Client.IOHandler.Write(Buffer); end; procedure TServerFrmMain.ServerExecute(AContext: TIdContext); var MIRec: Tmyrecord; Buffer: TIdBytes; begin AContext.Connection.IOHandler.ReadBytes(Buffer,SizeOf(MIRec)); BytesToRaw(Buffer,MIRec,SizeOf(MIRec)); ... end; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |