我想做一个P2P文件传输的小程序!控件就直接使用DELPHI Internet 页面上的TClientSocket和TServerSocket这组控件来实现!我找了一些参考资料后写出了这段程序!可是最终没办法调试通过!我把客户端和服务端的源代码贴出来,在此想请哪位高手帮忙调试一下!成功后100分送上!急啊!各位哥哥!
客户端(UnClient):
unit UnClient;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ScktComp, Math;type
TfmClient = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
StatusBar1: TStatusBar;
Edit2: TEdit;
SaveDialog1: TSaveDialog;
ClientSocket: TClientSocket;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
private
procedure Delay(Msecs: Integer); //延时函数
{ Private declarations }
public
{ Public declarations }
end;var
fmClient: TfmClient;implementation
var
cmd: string;{$R *.dfm}
procedure TfmClient.Delay(Msecs: Integer); //延时函数
var
FirstTickCount : real;
begin
FirstTickCount := GetTickCount;
Repeat
Application.ProcessMessages;
Until ((GetTickCount - FirstTickCount) >= LongInt (Msecs));
end;
procedure TfmClient.Button1Click(Sender: TObject);
var ASize, TotalSize: Int64;
AFileStream: TFileStream;
begin
ClientSocket.Address := Edit1.Text; //连接主机
ClientSocket.Port := 6603; //端口
ClientSocket.Active :=True; //连接
end;procedure TfmClient.ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ClientSocket.Socket.SendText('BEGIN'); //提示服务器开始接收
end;procedure TfmClient.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
ASize, TotalSize: Int64;
AFileStream: TFileStream;
PData:Pointer;
begin
try
//以“|”符号分离文件名
cmd := Socket.ReceiveText;
SaveDialog1.FileName := Copy(cmd, Pos('|', cmd) + 1, Length(cmd));
if Not SaveDialog1.Execute then
begin
ClientSocket.Socket.SendText('CANCEL'); //告诉服务器取消
ClientSocket.Active :=False ; //断开连接
exit;
end;
TotalSize := StrToInt(Copy(cmd, 0, Pos('|', cmd) - 1)); //分离文件大小
//建立文件流准备接收
AFileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate);
try //循环开始接受
repeat
ClientSocket.Socket.SendText(IntToStr(AFileStream.Size));//发送当前传输的位置
ASize := Min(TotalSize - AFileStream.Size,Socket.ReceiveLength());//
//选择剩余大小和缓冲区大小小的一个作为传输的大小
ClientSocket.Socket.ReceiveBuf(AFileStream, Socket.ReceiveLength()); //接收流
StatusBar1.SimpleText := Format('当前传输位置%d/大小%d', [AFileStream.Size, Socket.ReceiveLength()]);
Application.ProcessMessages;
until AFileStream.Size = TotalSize; //大小一致了表示结束
finally
AFileStream.Free; //释放文件流
end;
ClientSocket.Socket.SendText('END'); //提示服务器传输完成
StatusBar1.SimpleText := '传输完成...';
except
StatusBar1.SimpleText := '连接服务器失败或者对方已经中断传输!';
end;
ClientSocket.Active :=False ;
end;end.
服务端(UnServer):
unit UnServer;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ScktComp, Math;type
TfmServer = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
ProgressBar1: TProgressBar;
StatusBar1: TStatusBar;
Edit1: TEdit;
Button4: TButton;
Edit2: TEdit;
OpenDialog1: TOpenDialog;
ServerSocket: TServerSocket;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
AFileStream: TFileStream; //传输的文件流
procedure ButtonBegin;
procedure ButtonEnd;
{ Private declarations }
public
{ Public declarations }
end;var
fmServer: TfmServer;
Const
MAX_LEN=2048;implementation
var
cmd: string; //接收到客户端的字符串信息
{$R *.dfm}procedure TfmServer.ButtonBegin;
begin //VCL开始状态设置
Button1.Enabled := False;
Button2.Enabled := False;
Button3.Enabled := True;
Button4.Enabled := False;
end;procedure TfmServer.ButtonEnd;
begin //VCL结束状态设置
Button1.Enabled := True;
Button2.Enabled := True;
Button3.Enabled := False;
Button4.Enabled := True;
end;
procedure TfmServer.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
Edit1.Text := OpenDialog1.FileName;
end;procedure TfmServer.Button2Click(Sender: TObject);
begin
if not FileExists(Edit1.Text) then //检测文件是否存在
begin
Showmessage('文件不存在,请选择文件!');
exit;
end;
//建立文件流
AFileStream := TFileStream.Create(Edit1.Text, fmOpenRead);
ProgressBar1.Max := AFileStream.Size;
ProgressBar1.Position := 0;
ButtonBegin; //VCL开始状态设置
//服务器准备好连接
ServerSocket.Port := StrToIntDef(Edit2.Text, 6603);
if not ServerSocket.Active then ServerSocket.Active := True;
end;procedure TfmServer.Button3Click(Sender: TObject);
begin
StatusBar1.SimpleText := '传输取消...';
AFileStream.Free; //释放文件流
ButtonEnd; //VCL结束状态设置
end;procedure TfmServer.Button4Click(Sender: TObject);
begin
Close;
end;procedure TfmServer.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
ASize: Integer; //需要传输的流大小
buf:array[1..MAX_LEN]of char;begin
cmd := UpperCase(Socket.ReceiveText); //客户端发送的命令字符串
if cmd = 'BEGIN' then //开始传输
begin
//告诉远程传输文件的大小和文件名
Socket.SendText(Format('%d|%s', [AFileStream.Size, ExtractFileName(Edit1.Text)]));
StatusBar1.SimpleText := '准备传输...';
Exit;
end;
if cmd = 'END' then
begin //传输完成
Button3.Click;
StatusBar1.SimpleText := '传输完成...';
Exit;
end;
if cmd = 'CANCEL' then
begin //传输取消
StatusBar1.SimpleText := '传输取消...';
//保持传输状态
Exit;
end;
//按照指定位置传输文件
AFileStream.Seek(StrToInT(cmd), soFromBeginning); //转到文件流传输的位置
ASize := Min(AFileStream.Size - AFileStream.Position, Socket.ReceiveLength()); //
AFileStream.ReadBuffer(Buf,MAX_LEN);
Socket.SendBuf(Buf,MAX_LEN);
//计算需要发送的大小,Min()函数在Math单元
//OpenWriteBuffer; //准备发送缓冲
//WriteStream(AFileStream, false, false, ASize);
//注意这个函数的参数。
//CloseWriteBuffer; //结束发送缓冲
StatusBar1.SimpleText := Format('当前传输位置%s/大小%d', [cmd, AFileStream.Size]);
ProgressBar1.Position := ProgressBar1.Position + ASize;end;end.
客户端(UnClient):
unit UnClient;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ScktComp, Math;type
TfmClient = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
StatusBar1: TStatusBar;
Edit2: TEdit;
SaveDialog1: TSaveDialog;
ClientSocket: TClientSocket;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
private
procedure Delay(Msecs: Integer); //延时函数
{ Private declarations }
public
{ Public declarations }
end;var
fmClient: TfmClient;implementation
var
cmd: string;{$R *.dfm}
procedure TfmClient.Delay(Msecs: Integer); //延时函数
var
FirstTickCount : real;
begin
FirstTickCount := GetTickCount;
Repeat
Application.ProcessMessages;
Until ((GetTickCount - FirstTickCount) >= LongInt (Msecs));
end;
procedure TfmClient.Button1Click(Sender: TObject);
var ASize, TotalSize: Int64;
AFileStream: TFileStream;
begin
ClientSocket.Address := Edit1.Text; //连接主机
ClientSocket.Port := 6603; //端口
ClientSocket.Active :=True; //连接
end;procedure TfmClient.ClientSocketConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ClientSocket.Socket.SendText('BEGIN'); //提示服务器开始接收
end;procedure TfmClient.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
ASize, TotalSize: Int64;
AFileStream: TFileStream;
PData:Pointer;
begin
try
//以“|”符号分离文件名
cmd := Socket.ReceiveText;
SaveDialog1.FileName := Copy(cmd, Pos('|', cmd) + 1, Length(cmd));
if Not SaveDialog1.Execute then
begin
ClientSocket.Socket.SendText('CANCEL'); //告诉服务器取消
ClientSocket.Active :=False ; //断开连接
exit;
end;
TotalSize := StrToInt(Copy(cmd, 0, Pos('|', cmd) - 1)); //分离文件大小
//建立文件流准备接收
AFileStream := TFileStream.Create(SaveDialog1.FileName, fmCreate);
try //循环开始接受
repeat
ClientSocket.Socket.SendText(IntToStr(AFileStream.Size));//发送当前传输的位置
ASize := Min(TotalSize - AFileStream.Size,Socket.ReceiveLength());//
//选择剩余大小和缓冲区大小小的一个作为传输的大小
ClientSocket.Socket.ReceiveBuf(AFileStream, Socket.ReceiveLength()); //接收流
StatusBar1.SimpleText := Format('当前传输位置%d/大小%d', [AFileStream.Size, Socket.ReceiveLength()]);
Application.ProcessMessages;
until AFileStream.Size = TotalSize; //大小一致了表示结束
finally
AFileStream.Free; //释放文件流
end;
ClientSocket.Socket.SendText('END'); //提示服务器传输完成
StatusBar1.SimpleText := '传输完成...';
except
StatusBar1.SimpleText := '连接服务器失败或者对方已经中断传输!';
end;
ClientSocket.Active :=False ;
end;end.
服务端(UnServer):
unit UnServer;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls, ScktComp, Math;type
TfmServer = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
ProgressBar1: TProgressBar;
StatusBar1: TStatusBar;
Edit1: TEdit;
Button4: TButton;
Edit2: TEdit;
OpenDialog1: TOpenDialog;
ServerSocket: TServerSocket;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
AFileStream: TFileStream; //传输的文件流
procedure ButtonBegin;
procedure ButtonEnd;
{ Private declarations }
public
{ Public declarations }
end;var
fmServer: TfmServer;
Const
MAX_LEN=2048;implementation
var
cmd: string; //接收到客户端的字符串信息
{$R *.dfm}procedure TfmServer.ButtonBegin;
begin //VCL开始状态设置
Button1.Enabled := False;
Button2.Enabled := False;
Button3.Enabled := True;
Button4.Enabled := False;
end;procedure TfmServer.ButtonEnd;
begin //VCL结束状态设置
Button1.Enabled := True;
Button2.Enabled := True;
Button3.Enabled := False;
Button4.Enabled := True;
end;
procedure TfmServer.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
Edit1.Text := OpenDialog1.FileName;
end;procedure TfmServer.Button2Click(Sender: TObject);
begin
if not FileExists(Edit1.Text) then //检测文件是否存在
begin
Showmessage('文件不存在,请选择文件!');
exit;
end;
//建立文件流
AFileStream := TFileStream.Create(Edit1.Text, fmOpenRead);
ProgressBar1.Max := AFileStream.Size;
ProgressBar1.Position := 0;
ButtonBegin; //VCL开始状态设置
//服务器准备好连接
ServerSocket.Port := StrToIntDef(Edit2.Text, 6603);
if not ServerSocket.Active then ServerSocket.Active := True;
end;procedure TfmServer.Button3Click(Sender: TObject);
begin
StatusBar1.SimpleText := '传输取消...';
AFileStream.Free; //释放文件流
ButtonEnd; //VCL结束状态设置
end;procedure TfmServer.Button4Click(Sender: TObject);
begin
Close;
end;procedure TfmServer.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
ASize: Integer; //需要传输的流大小
buf:array[1..MAX_LEN]of char;begin
cmd := UpperCase(Socket.ReceiveText); //客户端发送的命令字符串
if cmd = 'BEGIN' then //开始传输
begin
//告诉远程传输文件的大小和文件名
Socket.SendText(Format('%d|%s', [AFileStream.Size, ExtractFileName(Edit1.Text)]));
StatusBar1.SimpleText := '准备传输...';
Exit;
end;
if cmd = 'END' then
begin //传输完成
Button3.Click;
StatusBar1.SimpleText := '传输完成...';
Exit;
end;
if cmd = 'CANCEL' then
begin //传输取消
StatusBar1.SimpleText := '传输取消...';
//保持传输状态
Exit;
end;
//按照指定位置传输文件
AFileStream.Seek(StrToInT(cmd), soFromBeginning); //转到文件流传输的位置
ASize := Min(AFileStream.Size - AFileStream.Position, Socket.ReceiveLength()); //
AFileStream.ReadBuffer(Buf,MAX_LEN);
Socket.SendBuf(Buf,MAX_LEN);
//计算需要发送的大小,Min()函数在Math单元
//OpenWriteBuffer; //准备发送缓冲
//WriteStream(AFileStream, false, false, ASize);
//注意这个函数的参数。
//CloseWriteBuffer; //结束发送缓冲
StatusBar1.SimpleText := Format('当前传输位置%s/大小%d', [cmd, AFileStream.Size]);
ProgressBar1.Position := ProgressBar1.Position + ASize;end;end.
解决方案 »
- XMLDocument的问题,偶尔访问出错,百思不得其解。
- windowsmediaplayer的奇怪问题,请问怎么解决?
- 利用IP地址连接网络数据库
- 请问如何把一些小图片存在sql server数据库里面?
- 如何判断窗体(form)是否处于开启状态!!!
- 心情不好,想散分。
- 新手求助,用delphi做一个端口扫描器报错
- 有没有类似C中Memcpy的函数?在线等!
- 如何改变StringGrid一行的背景颜色?
- 我从MSSQLSERVER上COPY一个DB到C:\打开时汉字显示####,我该如何解决
- 通过程序调用硬盘上的SQL脚本,运行。
- 急:1、程序运行一段时间界面自动关闭,但是进程还存在;2、多线程中定时器的使用。
www.wyx2008.com/mxj/p2p.zip
用VC+Winsock API写的
我研究了下 比较简单 稍微改造下把他移植到delphi就可以了