这很简单 function DoSendFile(FileName: string; IP, Port: Integer): Boolean; var Stream: TFileStream; TcpClient: TTcpClient; label: RET; begin //创建文件流 try Stream := TFileStream.Create(FileName, fmOpenRead); except Result := False; goto RET; end; //创建TCP连接 TcpClient := TTcpClient.Create(Self); try TcpClient.RemoteHost := IPToString(IP); TcpClient.RemotePort := Port; TcpClent.Active := False; except Result := False; end;RET: Stream.Free; TcpClient.Free;
function DoSendFile(FileName: string; IP, Port: Integer): Boolean; var Stream: TFileStream; TcpClient: TTcpClient; ReadCount, LCount: Integer; Buffer: array[0..1023] of Char; label: RET; begin //创建文件流 try Stream := TFileStream.Create(FileName, fmOpenRead); except Result := False; goto RET; end; //创建TCP连接 TcpClient := TTcpClient.Create(Self); try TcpClient.RemoteHost := IPToString(IP); TcpClient.RemotePort := Port; TcpClent.Active := False; except Result := False; goto RET; end; //传送文件 LCount := Stream.Size; while LCount > 0 do begin //网络中断 if not TcpClient.Connected then Break; ReadCount := Min(1024, LCount); Stream.Read(Buffer, ReadCount); TcpClient.SendBuf(Buffer, ReadCount); end; if LCount = 0 then Result := True else Result := False; RET: Stream.Free; TcpClient.Free end;大致上就是这样了,细节如异常,计数等自已可加上.
//server部分 procedure TForm1.TCPServerExecute(AThread: TIdPeerThread); var SRequest: string; begin with AThread.Connection do begin AThread.Synchronize(IncrConnectionCount); WriteLn('Welcome to Auto Update Server'); try SRequest := UpperCase(ReadLn); //傳送檔案 if SRequest = 'GETFILE' then //傳檔需求 begin WriteLn('FILENAME?'); //尋問要取那一個檔 SRequest := UpperCase(ReadLn); SendFile(AThread, SRequest);//這裡是將一個檔案變成Stream end;finally Disconnect; AThread.Synchronize(DecrConnectionCount); end; end; end; --------------------------------------------------------------------------------引言: --------------------------------------------------------------------------------//client部分 function TForm1.GetFiles(SaveFilePath: string; iFileName: Tstrings): boolean; var FStream: TFileStream; i:integer; SResponse: string; begin try TCPClient.Connect(); while TCPClient.Connected do begin SResponse := UpperCase(TCPClient.ReadLn); //讀取伺服器回應 if Pos('WELCOME', SResponse) = 0 then break; //若無回應則離開TCPClient.WriteLn('GETFILE'); SResponse := UpperCase(TCPClient.ReadLn); //讀取伺服器回應 for i:=0 to iFileName.Count-1 do begin TCPClient.WriteLn(iFileName.Strings[i]); try FStream := TFileStream.Create(SaveFilePath + '\' + iFileName.Strings[i], fmCreate); FStream.Seek(0, soFromBeginning); TCPClient.ReadStream(FStream, -1, True); finally FStream.Free; end; end; end; finally TCPClient.Disconnect; end; end;
支持線程的, 到了d7中比較常用! 我的Server端, 還是用到了
D6+Win200 下调试通过 --------------------点对点文件传输---------------------------采用的协议: 此协议是在前人基础上,在末尾整理了一下,应该没什么问题 首先由Client发送MP_QUERY,Server接受到后发送MP_ACCEPT或MP_FEFUESE; Client接受到MP_ACCEPT发送MP_FILEPROPERTY,Server接受到后发送MP_NEXTWILLBEDATA; Client接受到发送MP_NEXTWILLBEDATA,Server接受到后发送MP_DATA; Client接受到MP_DATA,发送数据块,Server接受数据块, Server还没接受完,发送MP_NEXTWILLBEDATA,否则发送MP_END Client接受MP_END后,向Server发送MP_END; Server收到MP_END后,停止发送。至此,整个文件传输完毕! ----------------------服务器端---------------------------- unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, StdCtrls; Const MP_QUERY ='1'; MP_REFUSE ='2'; MP_ACCEPT ='3'; MP_NEXTWILLBEDATA='4'; MP_DATA ='5'; MP_ABORT ='6'; MP_OVER ='7'; MP_CHAT ='8'; MP_END ='9'; MP_FILEPROPERTY ='0'; iBYTEPERSEND=1024; type TForm1 = class(TForm) btnstartServer: TButton; Edit1: TEdit; Edit2: TEdit; ss: TServerSocket; SaveDialog1: TSaveDialog; Memo1: TMemo; Button1: TButton; Edit3: TEdit; procedure btnstartServerClick(Sender: TObject); procedure ssClientConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket); procedure ssClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private fsRecv:TMemoryStream; public { Public declarations } end;var Form1: TForm1; bReadText:boolean; implementation{$R *.dfm}procedure TForm1.btnstartServerClick(Sender: TObject); begin ss.Port:=2000; bReadText := true; Edit1.Text:='Server is listening'; ss.Open; end;procedure TForm1.ssClientConnect(Sender: TObject; Socket: TCustomWinSocket); begin Edit1.Text:='Server is connected by'+Socket.RemoteAddress; end;procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket); var sTemp:string; bufRecv:Pointer; iNum:integer; begin Memo1.Lines.Add('received size :' + intToStr(Socket.ReceiveLength)); if bReadText then begin sTemp:=Socket.ReceiveText; case sTemp[1] of MP_QUERY: begin Memo1.Lines.Add('receive MP_QUERY'); SaveDialog1.FileName:=Copy(sTemp,2,Length(STemp)); if SaveDialog1.Execute then begin // ss.Socket.SendText(MP_ACCEPT); ss.Socket.Connections[0].SendText(MP_ACCEPT); fsRecv := TMemoryStream.Create; // fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate); edit2.Text := SaveDialog1.FileName; end else ss.Socket.Connections[0].SendText(MP_REFUSE+''); end; MP_FILEPROPERTY: begin Memo1.Lines.Add('receive MP_FILEPROPERTY'); ss.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA); end; MP_NEXTWILLBEDATA: begin Memo1.Lines.Add('receive MP_NEXTWILLBEDATA'); bReadText:=false; ss.Socket.Connections[0].SendText(MP_DATA); end; MP_END: begin Memo1.Lines.Add('receive MP_END'); fsRecv.Free; bReadText:=true; end; MP_ABORT: begin Memo1.Lines.Add('receive MP_ABORT'); fsRecv.Free; bReadText:=true; end; MP_CHAT: begin Memo1.Lines.Add('receive MP_CHAT'); end; end;{of case} end else begin try GetMem(bufRecv, iBYTEPERSEND); iNum := Socket.ReceiveBuf(bufRecv^, iBYTEPERSEND); fsRecv.WriteBuffer(bufRecv^, iNum); finally FreeMem(bufRecv); end;{of try} bReadText:=true; if iNum = iBYTEPERSEND THEN begin ss.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA); end else begin fsRecv.SaveToFile(SaveDialog1.FileName); fsRecv.Free; ss.Socket.Connections[0].SendText(MP_END); end; end; end; procedure TForm1.ssClientError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); begin Memo1.Lines.Add('ErrorCode :' + IntToStr(ErrorCode)); ErrorCode := 0; end;procedure TForm1.Button1Click(Sender: TObject); var I, j: integer; begin J := ss.Socket.ActiveConnections; Memo1.Lines.Add('ActiveConnectiong is ' + inttostr(j)); for I:= 0 to j- 1 do ss.Socket.Connections[i].SendText(edit3.Text) end;procedure TForm1.FormCreate(Sender: TObject); begin ss.Port:=2000; bReadText := true; Edit1.Text:='Server is listening'; ss.Open; end; end.----------------------客户端---------------------------- unit clientSocketu;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ScktComp; Const MP_QUERY ='1'; MP_REFUSE ='2'; MP_ACCEPT ='3'; MP_NEXTWILLBEDATA='4'; MP_DATA ='5'; MP_ABORT ='6'; MP_OVER ='7'; MP_CHAT ='8'; MP_END ='9'; MP_FILEPROPERTY ='0'; iBYTEPERSEND=1024; type TForm1 = class(TForm) btnConnect: TButton; btnSendFile: TButton; Edit1: TEdit; Edit2: TEdit; cs: TClientSocket; Label1: TLabel; edtIPAddress: TEdit; edtSize: TEdit; OpenDialog1: TOpenDialog; Memo1: TMemo; procedure btnConnectClick(Sender: TObject); procedure btnSendFileClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure csRead(Sender: TObject; Socket: TCustomWinSocket); private fsSend:TFileStream; 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.FormCreate(Sender: TObject); begin edit1.Color:=clBlack; edit1.Font.Color:=clLime; end;procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket); var sRecv:string; // sTemp:string; iNum:integer; bufSend:pointer; begin // GetMem(bufSend,iBytePersend+1); sRecv:=Socket.ReceiveText; Memo1.Lines.Add('sRecv = ' + sRecv); Case sRecv[1] of MP_REFUSE:ShowMessage('Faint,be refused!'); MP_ACCEPT:begin Memo1.Lines.Add('MP_ACCEPT'); fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead); //iBYTEPERSEND琌熌盽秖–Ω塝癳 edtSize.Text:=IntToStr(fsSend.Size); edit2.text:='total count:'+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1); cs.Socket.SendText(MP_FILEPROPERTY+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1)); fsSend.Seek(0, soFromBeginning); end; MP_NEXTWILLBEDATA:begin Memo1.Lines.Add('MP_NEXTWILLBEDATA'); Socket.SendText(MP_NEXTWILLBEDATA); end; MP_DATA: begin Memo1.Lines.Add('MP_DATA'); try GetMem(bufSend, iBYTEPERSEND); iNum := fsSend.Read(bufSend^, iBYTEPERSEND); cs.Socket.SendBuf(bufSend^, iNum); // Socket.SendBuf(bufSend,iNum); Memo1.Lines.Add('Send Buf finished'); finally FreeMem(bufSend); end;{of try} end; MP_END: begin Memo1.Lines.Add('MP_END'); fsSend.Free; end; MP_ABORT:begin Memo1.Lines.Add('MP_ABORT'); fsSend.Free; end; end;{of case} end; end.
function DoSendFile(FileName: string; IP, Port: Integer): Boolean;
var
Stream: TFileStream;
TcpClient: TTcpClient;
label:
RET;
begin
//创建文件流
try
Stream := TFileStream.Create(FileName, fmOpenRead);
except
Result := False;
goto RET;
end; //创建TCP连接
TcpClient := TTcpClient.Create(Self);
try
TcpClient.RemoteHost := IPToString(IP);
TcpClient.RemotePort := Port;
TcpClent.Active := False;
except
Result := False; end;RET:
Stream.Free;
TcpClient.Free;
var
Stream: TFileStream;
TcpClient: TTcpClient;
ReadCount, LCount: Integer;
Buffer: array[0..1023] of Char;
label:
RET;
begin
//创建文件流
try
Stream := TFileStream.Create(FileName, fmOpenRead);
except
Result := False;
goto RET;
end; //创建TCP连接
TcpClient := TTcpClient.Create(Self);
try
TcpClient.RemoteHost := IPToString(IP);
TcpClient.RemotePort := Port;
TcpClent.Active := False;
except
Result := False;
goto RET;
end; //传送文件
LCount := Stream.Size;
while LCount > 0 do
begin
//网络中断
if not TcpClient.Connected then Break;
ReadCount := Min(1024, LCount);
Stream.Read(Buffer, ReadCount);
TcpClient.SendBuf(Buffer, ReadCount);
end; if LCount = 0 then
Result := True
else
Result := False;
RET:
Stream.Free;
TcpClient.Free
end;大致上就是这样了,细节如异常,计数等自已可加上.
procedure TForm1.TCPServerExecute(AThread: TIdPeerThread);
var
SRequest: string;
begin
with AThread.Connection do
begin
AThread.Synchronize(IncrConnectionCount);
WriteLn('Welcome to Auto Update Server');
try
SRequest := UpperCase(ReadLn);
//傳送檔案
if SRequest = 'GETFILE' then //傳檔需求
begin
WriteLn('FILENAME?'); //尋問要取那一個檔
SRequest := UpperCase(ReadLn);
SendFile(AThread, SRequest);//這裡是將一個檔案變成Stream
end;finally
Disconnect;
AThread.Synchronize(DecrConnectionCount);
end;
end;
end;
--------------------------------------------------------------------------------引言:
--------------------------------------------------------------------------------//client部分
function TForm1.GetFiles(SaveFilePath: string; iFileName: Tstrings): boolean;
var
FStream: TFileStream;
i:integer;
SResponse: string;
begin
try
TCPClient.Connect();
while TCPClient.Connected do
begin
SResponse := UpperCase(TCPClient.ReadLn); //讀取伺服器回應
if Pos('WELCOME', SResponse) = 0 then
break; //若無回應則離開TCPClient.WriteLn('GETFILE');
SResponse := UpperCase(TCPClient.ReadLn); //讀取伺服器回應
for i:=0 to iFileName.Count-1 do
begin
TCPClient.WriteLn(iFileName.Strings[i]);
try
FStream := TFileStream.Create(SaveFilePath + '\' + iFileName.Strings[i], fmCreate);
FStream.Seek(0, soFromBeginning);
TCPClient.ReadStream(FStream, -1, True);
finally
FStream.Free;
end;
end;
end;
finally
TCPClient.Disconnect;
end;
end;
我的Server端, 還是用到了
--------------------点对点文件传输---------------------------采用的协议:
此协议是在前人基础上,在末尾整理了一下,应该没什么问题
首先由Client发送MP_QUERY,Server接受到后发送MP_ACCEPT或MP_FEFUESE;
Client接受到MP_ACCEPT发送MP_FILEPROPERTY,Server接受到后发送MP_NEXTWILLBEDATA;
Client接受到发送MP_NEXTWILLBEDATA,Server接受到后发送MP_DATA;
Client接受到MP_DATA,发送数据块,Server接受数据块,
Server还没接受完,发送MP_NEXTWILLBEDATA,否则发送MP_END
Client接受MP_END后,向Server发送MP_END;
Server收到MP_END后,停止发送。至此,整个文件传输完毕!
----------------------服务器端----------------------------
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, StdCtrls;
Const
MP_QUERY ='1';
MP_REFUSE ='2';
MP_ACCEPT ='3';
MP_NEXTWILLBEDATA='4';
MP_DATA ='5';
MP_ABORT ='6';
MP_OVER ='7';
MP_CHAT ='8';
MP_END ='9';
MP_FILEPROPERTY ='0';
iBYTEPERSEND=1024;
type
TForm1 = class(TForm)
btnstartServer: TButton;
Edit1: TEdit;
Edit2: TEdit;
ss: TServerSocket;
SaveDialog1: TSaveDialog;
Memo1: TMemo;
Button1: TButton;
Edit3: TEdit;
procedure btnstartServerClick(Sender: TObject);
procedure ssClientConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ssClientError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
fsRecv:TMemoryStream;
public
{ Public declarations }
end;var
Form1: TForm1;
bReadText:boolean;
implementation{$R *.dfm}procedure TForm1.btnstartServerClick(Sender: TObject);
begin
ss.Port:=2000;
bReadText := true;
Edit1.Text:='Server is listening';
ss.Open;
end;procedure TForm1.ssClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Edit1.Text:='Server is connected by'+Socket.RemoteAddress;
end;procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
sTemp:string;
bufRecv:Pointer;
iNum:integer;
begin
Memo1.Lines.Add('received size :' + intToStr(Socket.ReceiveLength));
if bReadText then
begin
sTemp:=Socket.ReceiveText;
case sTemp[1] of
MP_QUERY:
begin
Memo1.Lines.Add('receive MP_QUERY');
SaveDialog1.FileName:=Copy(sTemp,2,Length(STemp));
if SaveDialog1.Execute then
begin
// ss.Socket.SendText(MP_ACCEPT);
ss.Socket.Connections[0].SendText(MP_ACCEPT); fsRecv := TMemoryStream.Create;
// fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);
edit2.Text := SaveDialog1.FileName;
end
else
ss.Socket.Connections[0].SendText(MP_REFUSE+'');
end;
MP_FILEPROPERTY:
begin
Memo1.Lines.Add('receive MP_FILEPROPERTY');
ss.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA);
end;
MP_NEXTWILLBEDATA:
begin
Memo1.Lines.Add('receive MP_NEXTWILLBEDATA');
bReadText:=false;
ss.Socket.Connections[0].SendText(MP_DATA);
end;
MP_END:
begin
Memo1.Lines.Add('receive MP_END');
fsRecv.Free;
bReadText:=true;
end;
MP_ABORT:
begin
Memo1.Lines.Add('receive MP_ABORT');
fsRecv.Free;
bReadText:=true;
end;
MP_CHAT:
begin
Memo1.Lines.Add('receive MP_CHAT');
end;
end;{of case}
end
else
begin
try GetMem(bufRecv, iBYTEPERSEND);
iNum := Socket.ReceiveBuf(bufRecv^, iBYTEPERSEND);
fsRecv.WriteBuffer(bufRecv^, iNum);
finally
FreeMem(bufRecv);
end;{of try}
bReadText:=true; if iNum = iBYTEPERSEND THEN
begin
ss.Socket.Connections[0].SendText(MP_NEXTWILLBEDATA);
end
else
begin
fsRecv.SaveToFile(SaveDialog1.FileName);
fsRecv.Free;
ss.Socket.Connections[0].SendText(MP_END);
end;
end;
end;
procedure TForm1.ssClientError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
Memo1.Lines.Add('ErrorCode :' + IntToStr(ErrorCode));
ErrorCode := 0;
end;procedure TForm1.Button1Click(Sender: TObject);
var I, j: integer;
begin
J := ss.Socket.ActiveConnections;
Memo1.Lines.Add('ActiveConnectiong is ' + inttostr(j));
for I:= 0 to j- 1 do
ss.Socket.Connections[i].SendText(edit3.Text)
end;procedure TForm1.FormCreate(Sender: TObject);
begin
ss.Port:=2000;
bReadText := true;
Edit1.Text:='Server is listening';
ss.Open;
end;
end.----------------------客户端----------------------------
unit clientSocketu;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp;
Const
MP_QUERY ='1';
MP_REFUSE ='2';
MP_ACCEPT ='3';
MP_NEXTWILLBEDATA='4';
MP_DATA ='5';
MP_ABORT ='6';
MP_OVER ='7';
MP_CHAT ='8';
MP_END ='9';
MP_FILEPROPERTY ='0';
iBYTEPERSEND=1024;
type
TForm1 = class(TForm)
btnConnect: TButton;
btnSendFile: TButton;
Edit1: TEdit;
Edit2: TEdit;
cs: TClientSocket;
Label1: TLabel;
edtIPAddress: TEdit;
edtSize: TEdit;
OpenDialog1: TOpenDialog;
Memo1: TMemo;
procedure btnConnectClick(Sender: TObject);
procedure btnSendFileClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure csRead(Sender: TObject; Socket: TCustomWinSocket);
private
fsSend:TFileStream;
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.FormCreate(Sender: TObject);
begin
edit1.Color:=clBlack;
edit1.Font.Color:=clLime;
end;procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);
var
sRecv:string;
// sTemp:string;
iNum:integer;
bufSend:pointer;
begin
// GetMem(bufSend,iBytePersend+1);
sRecv:=Socket.ReceiveText;
Memo1.Lines.Add('sRecv = ' + sRecv);
Case sRecv[1] of
MP_REFUSE:ShowMessage('Faint,be refused!');
MP_ACCEPT:begin
Memo1.Lines.Add('MP_ACCEPT');
fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);
//iBYTEPERSEND琌熌盽秖–Ω塝癳
edtSize.Text:=IntToStr(fsSend.Size);
edit2.text:='total count:'+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1); cs.Socket.SendText(MP_FILEPROPERTY+IntToStr(Trunc(fsSend.Size/iBYTEPERSEND)+1));
fsSend.Seek(0, soFromBeginning);
end;
MP_NEXTWILLBEDATA:begin
Memo1.Lines.Add('MP_NEXTWILLBEDATA');
Socket.SendText(MP_NEXTWILLBEDATA);
end;
MP_DATA:
begin
Memo1.Lines.Add('MP_DATA');
try
GetMem(bufSend, iBYTEPERSEND);
iNum := fsSend.Read(bufSend^, iBYTEPERSEND);
cs.Socket.SendBuf(bufSend^, iNum);
// Socket.SendBuf(bufSend,iNum);
Memo1.Lines.Add('Send Buf finished');
finally
FreeMem(bufSend);
end;{of try}
end;
MP_END:
begin
Memo1.Lines.Add('MP_END');
fsSend.Free;
end;
MP_ABORT:begin
Memo1.Lines.Add('MP_ABORT');
fsSend.Free;
end;
end;{of case}
end;
end.