unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, StdCtrls, ADODB, IdTCPServer,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;type
Tuser = record
s_id:array[0..50] of string;
s_name:array[0..50] of string;
s_age:array[0..50] of string;
s_text:array[0..50] of string;
dt_date:array[0..50] of TDateTime;
end; TForm1 = class(TForm)
ADOConnection1: TADOConnection;
Button1: TButton;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
Memo1: TMemo;
IdTCPClient1: TIdTCPClient;
IdTCPServer1: TIdTCPServer;
ADOQuery1: TADOQuery;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
strm: TMemoryStream;
//user:Tuser;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var i:integer; user:Tuser;
begin
strm:= TMemoryStream.Create; ADOQuery1.First;
while not ADOQuery1.Eof do
begin
for i:= 1 to ADOQuery1.RecordCount do
begin
user.s_id[i-1]:= ADOQuery1.FieldByName('i_id').AsString;
user.s_name[i-1]:= ADOQuery1.FieldByName('vc_name').AsString;
user.s_age[i-1]:= ADOQuery1.FieldByName('vc_age').AsString;
user.s_text[i-1]:= ADOQuery1.FieldByName('vc_text').AsString;
user.dt_date[i-1]:= ADOQuery1.FieldByName('dt_date').AsDateTime;
ADOQuery1.Next;
end;
end; strm.WriteBuffer(user,sizeof(Tuser)); self.IdTCPClient1.Host:='127.0.0.1';
self.IdTCPClient1.Port:=9999;
try
self.IdTCPClient1.Connect(5000);
//self.IdTCPClient1.Writebuffer(strm,sizeof(strm));
self.IdTCPClient1.WriteStream(strm,true,False);
self.IdTCPClient1.Disconnect;
except
on e:exception do
memo1.Lines.Add(e.Message);
end; strm.Free;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
with ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('select * from sy');
Open;
end;
self.IdTCPServer1.DefaultPort:=9999;
self.IdTCPServer1.Active:= true;
end;procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
i:integer; user:TUser;
begin
strm:= TMemoryStream.Create; with AThread.Connection do
begin
AThread.Connection.ReadStream(strm,-1,FALSE);// 跟踪:strm显示为strm(),证明数据没过来
strm.ReadBuffer(user,sizeof(TUser));
memo1.Lines.Add(user.s_id[1]); //没有看到user.s_id[1]的数据
end;
end;end.不知道具体应该怎么改,谢谢大家。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, StdCtrls, ADODB, IdTCPServer,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient;type
Tuser = record
s_id:array[0..50] of string;
s_name:array[0..50] of string;
s_age:array[0..50] of string;
s_text:array[0..50] of string;
dt_date:array[0..50] of TDateTime;
end; TForm1 = class(TForm)
ADOConnection1: TADOConnection;
Button1: TButton;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
Memo1: TMemo;
IdTCPClient1: TIdTCPClient;
IdTCPServer1: TIdTCPServer;
ADOQuery1: TADOQuery;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
strm: TMemoryStream;
//user:Tuser;
implementation{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var i:integer; user:Tuser;
begin
strm:= TMemoryStream.Create; ADOQuery1.First;
while not ADOQuery1.Eof do
begin
for i:= 1 to ADOQuery1.RecordCount do
begin
user.s_id[i-1]:= ADOQuery1.FieldByName('i_id').AsString;
user.s_name[i-1]:= ADOQuery1.FieldByName('vc_name').AsString;
user.s_age[i-1]:= ADOQuery1.FieldByName('vc_age').AsString;
user.s_text[i-1]:= ADOQuery1.FieldByName('vc_text').AsString;
user.dt_date[i-1]:= ADOQuery1.FieldByName('dt_date').AsDateTime;
ADOQuery1.Next;
end;
end; strm.WriteBuffer(user,sizeof(Tuser)); self.IdTCPClient1.Host:='127.0.0.1';
self.IdTCPClient1.Port:=9999;
try
self.IdTCPClient1.Connect(5000);
//self.IdTCPClient1.Writebuffer(strm,sizeof(strm));
self.IdTCPClient1.WriteStream(strm,true,False);
self.IdTCPClient1.Disconnect;
except
on e:exception do
memo1.Lines.Add(e.Message);
end; strm.Free;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
with ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('select * from sy');
Open;
end;
self.IdTCPServer1.DefaultPort:=9999;
self.IdTCPServer1.Active:= true;
end;procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
i:integer; user:TUser;
begin
strm:= TMemoryStream.Create; with AThread.Connection do
begin
AThread.Connection.ReadStream(strm,-1,FALSE);// 跟踪:strm显示为strm(),证明数据没过来
strm.ReadBuffer(user,sizeof(TUser));
memo1.Lines.Add(user.s_id[1]); //没有看到user.s_id[1]的数据
end;
end;end.不知道具体应该怎么改,谢谢大家。
或者会不会是我写的时候哪里出错了?没有写进去。
WriteStream(Stream,true,true (*注意这个参数,它实际了先发送四个字节作为后续Stream的实际长度,就形成了一个简单的网络协议*))因此,你只需要在接收端先接收4个字节作为长度,然后再根据这个长度来接收后续数据即可.个人建议楼主加深点网络编程方面的基础知识,先了解什么是TCP流协议.
楼上说的是一个办法。
另外可以将string改为固定长度,比如string[200]。另外Tdatetime也是传不了的,也用字符串传送吧
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, Grids, DBGrids, StdCtrls, ADODB, IdTCPServer,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient; type
Tuser = record
s_id:array[0..50] of string;
s_name:array[0..50] of string;
s_age:array[0..50] of string;
s_text:array[0..50] of string;
//dt_date:array[0..50] of TDateTime;
end; TForm1 = class(TForm)
ADOConnection1: TADOConnection;
Button1: TButton;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
Memo1: TMemo;
IdTCPClient1: TIdTCPClient;
IdTCPServer1: TIdTCPServer;
ADOQuery1: TADOQuery;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
private
{ Private declarations }
public
{ Public declarations }
end; var
Form1: TForm1;
strm: TMemoryStream;
//user:Tuser;
implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject);
var i:integer; user:Tuser; cmd:string;
begin
ADOQuery1.First;
//赋值
while not ADOQuery1.Eof do
begin
for i:= 1 to ADOQuery1.RecordCount do
begin
user.s_id[i-1]:= ADOQuery1.FieldByName('i_id').AsString;
user.s_name[i-1]:= ADOQuery1.FieldByName('vc_name').AsString;
user.s_age[i-1]:= ADOQuery1.FieldByName('vc_age').AsString;
user.s_text[i-1]:= ADOQuery1.FieldByName('vc_text').AsString;
//user.dt_date[i-1]:= ADOQuery1.FieldByName('dt_date').AsDateTime;
ADOQuery1.Next;
end;
end;
strm:= TMemoryStream.Create;
strm.WriteBuffer(user,sizeof(Tuser)); IdTCPClient1.Host:='127.0.0.1';
IdTCPClient1.Port:=9999;
try
self.IdTCPClient1.Connect(5000);
IdTCPClient1.WriteLn(IntToStr(strm.Size)); //向服务器发送流的大小,此时跳到服务器端
cmd:= IdTCPClient1.ReadLn; //接受服务器端的命令字符,在这里我暂时设置为空
IdTCPClient1.OpenWriteBuffer; //准备发送缓冲
IdTCPClient1.WriteStream(strm,true,true,strm.Size);
IdTCPClient1.CloseWriteBuffer; //结束发送缓冲 IdTCPClient1.Disconnect;
except
on e:exception do
memo1.Lines.Add(e.Message);
end; strm.Free;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
with ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add('select * from sy');
Open;
end;
self.IdTCPServer1.DefaultPort:=9999;
self.IdTCPServer1.Active:= true;
end; procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
i:integer; user:TUser; cmd:string;
begin
strm:= TMemoryStream.Create; with AThread.Connection do
begin
cmd:= Readln();//接收到client端传来的流长度
strm.Size:= StrToInt(cmd);//设置要接收的流的大小
WriteLn('BEGIN');//返回client端开始传输数据,此时跳转到client端 ReadStream(strm,-1,True); //这里报错 AV错误 strm.ReadBuffer(user,sizeof(TUser));
memo1.Lines.Add(user.s_id[1]);
end;
end; end.
Tuser = record
s_id:array[0..50] of string;
s_name:array[0..50] of string;
s_age:array[0..50] of string;
s_text:array[0..50] of string;
end;改成
Tuser = record
s_id:array[0..50] of string[100];
s_name:array[0..50] of string[100];
s_age:array[0..50] of string[100];
s_text:array[0..50] of string[100]; 中间就不要用什么MemoryStream了
发送就是IdTCPClient1.WriteBuffer(user,sizeof(user),true);接收用AThread.Connection.ReadBuffer(user,sizeof(user));我试过是可以的
客户端:procedure TForm1.BitBtn1Click(Sender: TObject);
var
i:integer;
user:Tuser;
begin
IdTCPClient1.Host:='127.0.0.1';
IdTCPClient1.Port:=9999;
try
self.IdTCPClient1.Connect(5000);
for i:= 0 to 50 do
begin
user.s_id[i]:= inttostr(i);
user.s_name[i]:= 'name'+inttostr(i);
user.s_age[i]:= 'age'+inttostr(i);
user.s_text[i]:= 'text'+inttostr(i); end;
IdTCPClient1.WriteBuffer(user,sizeof(user),true);
except
on e:exception do
memo1.Lines.Add(e.Message);
end;
IdTCPClient1.Disconnect;
end;服务端:procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
user:Tuser;
i:integer;
begin
AThread.Connection.ReadBuffer(user,sizeof(user));
for i:=0 to 50 do
memo1.Lines.Add(user.s_name[i]);
end;
关键是服务端要知道数据包的大小