比如一个定义为:
type
user = record
name: string[32];
password: string[32];
end;如何才能将它转换成Buf或Stream之类的进行发送,然后接收方又如何接收?
请各位高手帮助小弟一把啊!
type
user = record
name: string[32];
password: string[32];
end;如何才能将它转换成Buf或Stream之类的进行发送,然后接收方又如何接收?
请各位高手帮助小弟一把啊!
client端:
unit UnitClient;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, StdCtrls, Buttons, ExtCtrls;
Const
MP_QUERY ='11111';
MP_REFUSE ='22222';
MP_ACCEPT ='33333';
MP_NEXTWILLBEDATA='44444';
MP_DATA ='55555';
MP_ABORT ='66666';
MP_OVER ='77777';
MP_CHAT ='88888';
MP_END='99999';
MP_FILEPROPERTY='00000';
iBYTEPERSEND=1024;
type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
cs: TClientSocket;
Memo1: TMemo;
Panel1: TPanel;
btnSendFile: TBitBtn;
btnConnect: TBitBtn;
edtIPAddress: TEdit;
procedure btnConnectClick(Sender: TObject);
procedure btnSendFileClick(Sender: TObject);
procedure csRead(Sender: TObject; Socket: TCustomWinSocket);
procedure FormCreate(Sender: TObject);
private
fsSend: TFileStream;
bStart:Boolean;
TickCount:Longword;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.btnConnectClick(Sender: TObject);
begin
cs.Address:=edtIPAddress.Text;
cs.Port:=2000;
cs.Open;
end;
procedure TForm1.btnSendFileClick(Sender: TObject);
begin
if OpenDialog1.Execute then
Begin
cs.Socket.SendText(MP_QUERY+OpenDialog1.FileName);
//接收端是否准备好!
end;
end;
procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);
var
sRecv:string;
bufSend:pointer;
iLength:Integer;
begin
sRecv:=Socket.ReceiveText;
sRecv:=copy(sRecv,1,5);
if sRecv=MP_REFUSE then
memo1.Lines.Add('被拒绝!')
else if sRecv=MP_ACCEPT then
begin
fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
bStart:=False;
memo1.Lines.Add('开始发送!');
TickCount:=GetTickCount;
//iBYTEPERSEND是个常量,每次发送包的大小。
Socket.SendText(MP_FILEPROPERTY+inttostr(Trunc(fsSend.Size/iBYTEPERSEND)+1));
//创建文件流并发送文件长度。
end else if sRecv=MP_NEXTWILLBEDATA then
begin
Socket.SendText(MP_NEXTWILLBEDATA);
//通知接收端。继续传送数据。
end else if sRecv=MP_DATA then
begin
//发送数据。
if not bStart then
begin
memo1.Lines.Add('发送数据!');
bStart:=True;
end;
if fsSend.Position< fsSend.Size-1 then//还有数据没有发送。
begin
iLength:=fsSend.Size-1-fsSend.Position;
if iLength>iBYTEPERSEND then
iLength:=iBYTEPERSEND;
GetMem(bufSend,iLength+1);
try
fsSend.Read(bufSend^,iLength);
Socket.SendBuf(bufSend^,iLength);
finally
FreeMem(bufSend,iLength+1);
end;{of try}
end else//没有数据需要发送了。
begin
Socket.SendText(MP_END);//文件传送结束。
memo1.Lines.Add('结束!'+IntToStr(GetTickCount-TickCount));
fsSend.Free; // <--------------------
end;
end else if sRecv=MP_ABORT then
begin
memo1.Lines.Add('中止!');
//被取消了:(
fsSend.Free;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
end;
end.
server端: unit UnitServer;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ScktComp, ExtCtrls;
Const
MP_QUERY ='11111';
MP_REFUSE ='22222';
MP_ACCEPT ='33333';
MP_NEXTWILLBEDATA='44444';
MP_DATA ='55555';
MP_ABORT ='66666';
MP_OVER ='77777';
MP_CHAT ='88888';
MP_END='99999';
MP_FILEPROPERTY='00000';
type
TForm1 = class(TForm)
SaveDialog1: TSaveDialog;
ss: TServerSocket;
Memo1: TMemo;
procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
fsRecv:TFileStream;
bStart:Boolean;
TickCount:Longword;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
sTemp,sFileName:string;
bufRecv:Pointer;
iLength:Integer;
begin
iLength:=Socket.ReceiveLength;
GetMem(bufRecv,iLength);
try
Socket.ReceiveBuf(bufRecv^,iLength); //
sTemp:=StrPas(PChar(bufRecv));
//如果传入的数据有可能不是字符串,需要用其他方式处理,则这里不能及Socket.ReceiveText方法取数据出来检查,
//因为这个方法会清空接收缓冲区,也就是说在执行Socket.ReceiveText方法后,Socket.ReceiveLength将会返回0,
//ReceiveBuf方法也不会取到正确数据。ReceiveBuf方法也是一样的!
//所以在取数据前一定要先把长度取出来,保存在一个变量中。
//请注意判断第一个字符的方法有可能出问题,有可能传送文件的时候正好当前传送段的数据的第一个字节是一个0-9之间的字符。可能会出错。
sTemp:=Copy(sTemp,1,5);
if sTemp=MP_QUERY then
begin
sTemp:=Trim(StrPas(PChar(bufRecv)));
sFileName:=ExtractFileName(Copy(sTemp,6,Length(STemp)));
//在这里拒绝
SaveDialog1.Title:='请选择或输入接收到的数据保存到的文件名:';
SaveDialog1.FileName:=sFileName;
if SaveDialog1.Execute then
begin
fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);
//如果愿意接收数据。
memo1.Lines.Add ('开始接收!');//??????
TickCount:=GetTickCount;
Socket.SendText(MP_ACCEPT);
//通知发送端发送数据。
bStart:=False;
end
else
Socket.SendText(MP_REFUSE+'去死');
end else if sTemp=MP_FILEPROPERTY then
begin
//要发送StrToInt(Copy(sTemp,2,Length(sTemp))) 次
//时间进度显示
//iRecvLength:=StrToInt(Copy(sTemp,2,Length(sTemp)));//;1024
Socket.SendText(MP_NEXTWILLBEDATA);
//接收文件长度并要求继续传送数据。
end else if sTemp=MP_NEXTWILLBEDATA then
begin
Socket.SendText(MP_DATA);
//要求发送端发送数据。
//准备好接收数据。
end else if sTemp=MP_OVER then
begin
memo1.Lines.Add ('MP_OVER');//??????
fsRecv.Free;
end else if sTemp=MP_END then//文件传送结束。
begin
memo1.Lines.Add ('结束!'+IntToStr(GetTickCount-TickCount));//??????
fsRecv.Free;
end else if sTemp=MP_ABORT then
begin
memo1.Lines.Add ('MP_ABORT');//??????
fsRecv.Free;
end else if sTemp=MP_CHAT then
begin
//Chat Msg
end else
begin
if not bStart then
begin
memo1.Lines.Add('接收数据...');//??????
bStart:=True;
end;
fsRecv.WriteBuffer(bufRecv^,iLength);//
Socket.SendText(MP_NEXTWILLBEDATA);
end;
finally
FreeMem(bufRecv,iLength);
//FreeMem(bufRecv,2000);
end;
end;
procedure TForm1.FormCreate(Send