我将程序贴在此,供大家批评指正。
服务端:
procedure TForm1.FormCreate(Sender: TObject);
begin
//开始侦听客户端的连接请求
ServerSocket1.Open;
//获取IP地址及子网掩码
EnumInterfaces(sIP,sMask);
//设置UDP的广播地址
NMUDP1.RemoteHost:=GetBCIP(sIp,sMask);
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
// OpenDialog1.InitialDir:='d:/game';
if OpenDialog1.Execute then
begin
Edit1.Text:=ExtractFileName(OpenDialog1.FileName);
FileSize:=GetFileSize(OpenDialog1.FileName);
fs:=TFilestream.Create(OpenDialog1.FileName,fmOpenRead);
Button1.Enabled:=true;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
DataStream:TMemoryStream;
begin
DataStream:=TMemoryStream.Create;
//将服务端的IP地址广播出去
DataStream.Write(sIP[1],length(sIP));
//NMUDP1的RemoteHost设为广播地址:192.168.1.255
NMUDP1.SendStream(DataStream);
DataStream.Free;
Button1.Enabled:=false;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
s:string;
i:integer;
begin
s:=OpenDialog1.FileName+'/'+InttoStr(FileSize);
Button2.Enabled:=false;
//首先发送文件名、文件大小信息
for i:=0 to ServerSocket1.socket.ActiveConnections-1 do
ServerSocket1.socket.Connections
.sendbuf(s[1],length(s));
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
const DataSize=1024;
var
ReTxt:string;
buffointer;
RealCount,i:integer;
begin
ReTxt:=socket.ReceiveText;
if ReTxt='Ready' then
//开始发送文件
begin
getmem(buff,datasize);
//RealCoun为实际读取的字节数
RealCount:=fs.Read(buff^,datasize);
//向所有已建立连接的客户端分批发送文件内容
for i:=0 to ServerSocket1.socket.ActiveConnections-1 do
ServerSocket1.socket.Connections.sendbuf(buff^,RealCount);
freemem(buff,DataSize);
end;
end;
procedure TForm1.NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer; FromIP: String);
var
Buff: string;
begin
setlength(Buff,NumberBytes);
NMUDP1.ReadBuffer(Buff[1],NumberBytes);
Memo1.Lines.Add(Buff);
Memo1.Lines.Add('客户端IP :'+FromIP);
Button2.Enabled:=true;
end;
客户端:
var
Form1: TForm1;
FileName:string;
FileSize:integer;
DestFileStream:TFileStream;
FilenfoReceived:Boolean; //表示是否已接收到文件名及文件大小信息
implementation
{$R *.DFM}
procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
const datasize=1024;
var RealCount:integer;
FileInfo:string;
Buffointer;
begin
if (not FilenfoReceived) then
begin
FilenfoReceived:=true;
FileInfo:=socket.ReceiveText;
FileName:=copy(FileInfo,1,pos('/',FileInfo)-1); //服务端发送的文件名与文件长度之间有一“/”
Memo1.lines.add('文件名:'+FileName);
FileSize:=StrToInt(copy(FileInfo,pos('/',FileInfo)+1,length(FileInfo)));
Memo1.lines.add('文件大小:'+Inttostr(FileSize)+' Byte');
ClientSocket1.Socket.SendText('Ready');
ProgressBar1.Max:=filesize;
ProgressBar1.Step:=1;
//建立目标文件
DestFileStream:=TFileStream.Create(ExtractFileName(FileName),fmCreate or fmOpenWrite);
end
else
//开始接收文件
begin
getmem(buff,datasize);
RealCount:=ClientSocket1.Socket.ReceiveBuf(Buff^,datasize);
DestFileStream.WriteBuffer(Buff^,RealCount); //将接收到的文件内容写入目标文件
edit1.Text:='已接收:'+inttostr(DestFileStream.size)+'Byte';
ProgressBar1.Position:=DestFileStream.Size;
ClientSocket1.Socket.SendText('Ready'); //返回一条信息,准备接收后续数据
freemem(buff);
if DestFileStream.size>=FileSize then
begin
Memo1.Lines.Add('文件传输完毕!');
DestFileStream.Free;
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FilenfoReceived:=false;
end;
procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
ClientSocket1.Socket.SendText('连接成功');
end;
procedure TForm1.NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer; FromIP: String);
var
MyStream:TMemoryStream;
TmpStr:string;
begin
Memo1.Lines.Add('服务端IP:'+FromIP);
TmpStr:='请发送文件!';
MyStream:=TMemoryStream.Create;
NMUDP1.RemoteHost:=FromIP;
//通知Server端,可以发送文件了
try
MyStream.Write(TmpStr[1],Length(TmpStr)); //将数据写入流中
NMUDP1.SendStream(MyStream);
finally
MyStream.Free;
end;
if ClientSocket1.Active then ClientSocket1.Close;
ClientSocket1.Host:=FromIP;
ClientSocket1.Active:=true;
end;