unit UnitServer;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;
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)
Ss: TServerSocket;
SaveDialog1: TSaveDialog;
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
ointer;
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.
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(Sender: TObject);
begin
Memo1.Clear;
ss.Port:=2000;
ss.Open;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ss.Close;
end;
end.
unit UnitClient;
interface
uses
Windows, Messages, SysUtils, Variants, 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)
Panel1: TPanel;
OpenDialog1: TOpenDialog;
btnSendfile: TBitBtn;
btnConnect: TBitBtn;
Cs: TClientSocket;
Memo1: TMemo;
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
ointer; 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.