大家帮我看看,TidTCPServer在同时发送同一个文件包给客户端的时候,只能发其中一个,怎样才能支持同时给客户端发同一文件包??
单个客户端是可行的,但是几个客户同时向服务器要同一文件包的时候就只能传一个了。服务器代码如下:大家帮我看看,应该怎么修改??
服务端://AwriteLn为客户端发送的内容,服务器端接到发送的内容会作出不同的回应
//AwriteLn = ILG + INI名称 FrmLogin调用,此窗口没有MEMO,ProgressBar1控件,
//AwriteLn = INI + INI名称 发送信息,让服务器传输 HPC_Version.INI的文本到本地
//AwriteLn = VSN + 版本号 发送信息,让服务器传输 该版本号的所有升级文件到本地
//AwriteLn = INF + 基本信息 发送用户信息,用户名+ 用户IP,中间用-隔开
//AwriteLn = SUC + 基本信息 发送到服务器,版本升级成功!
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
fStream : TFileStream;
aSize:integer;
Buf : array[0..1023*100] of Byte;
ReadCount: integer;
PathDir: string; //服务器升级文件存放的目录
s, sWriteFront, sWriteBack: string; //传送命令和 传送命令的前3位 和 传送命令的后几位(具体的信息)
sCom: string; //文件命令
LenStr, i, j, k: Integer; //传送命令的总长度
UserName, UserIP, Version: string; //传送过来的用户名和用户的本地IP
begin
PathDir := 'D:\DMS系统自动升级\' ;
try
s := uppercase(AThread.Connection.ReadLn);
sWriteFront := Copy(s, 1, 3);
LenStr := Length(s);
sWriteBack := Copy(s, 4, LenStr - 3); //根据客户端发送过来的命令,服务器发送相关的文件
if sWriteFront = 'INI' then sCom := '传送INI文本';
if sWriteFront = 'VSN' then
begin
sCom := sWriteBack + '传送版本数据';
PathDir := PathDir + 'DMS_HPC\'; //直接到 DMS_HPC 版本
end; if (sWriteFront = 'INF') then
begin
i := pos('-', s);
j := pos('#', s);
UserName := Copy(s, 4, i-4);
UserIP := Copy(s, i+1, j-i-1 );
Version := Copy(s, j+1, LenStr-j);
memo1.Lines.Add('[' + datetimetostr(now) + '] '
+ '用户:' + UserName + ' IP:'+UserIp
+ ' ' + Version +' 开始升级系统!') ;
CreateText( 'D:\DMS系统自动升级\HPC升级记录.txt', '[' + datetimetostr(now)+'] '
+ '用户:' + UserName + ' IP:' + UserIp + ' ' + Version + ' 开始升级系统!') ;
end; if sWriteFront = 'SUC' then
begin
memo1.Lines.Add('['+datetimetostr(now)+'] '+'接到指令' + sWriteFront + sCom) ;
CreateText( 'D:\DMS系统自动升级\HPC升级记录.txt', '[' + datetimetostr(now) + '] ' + sWriteBack) ;
end; if (sWriteFront = 'INI') or (sWriteFront = 'VSN') or (sWriteFront = 'ILG')then
Begin
try
if (sWriteFront = 'INI') or (sWriteFront = 'ILG') then //设置发送的类型
sWriteBack := sWriteBack + '.ini'
else
sWriteBack := sWriteBack + '.rar'; memo1.Lines.Add('[' + datetimetostr(now) + '] ' +'接到指令' + sWriteFront + sCom) ;
fstream:=tfilestream.Create(PathDir + sWriteBack, fmOpenRead + fmShareDenyNone);
AThread.Connection.WriteLn(ExtractFileName(sWriteBack));
AThread.Connection.ReadLn(#13#10, 1000) ; //多客户端时此报错
aSize:= fstream.Size;
AThread.Connection.WriteBuffer(aSize, 4);
memo1.Lines.Add( '[' + datetimetostr(now) + '] ' + '传送' + sWriteFront + '文件') ;
while fstream.Position < fstream.Size do
begin
if fstream.Size - fstream.Position >= SizeOf(Buf) then
ReadCount := sizeOf(Buf)
else ReadCount := fstream.Size - fstream.Position;
fstream.ReadBuffer(Buf, ReadCount);
try
AThread.Connection.WriteBuffer(Buf, ReadCount);
except
memo1.Lines.Add('AThread.Connection.WriteBuffer(Buf, ReadCount)'+' 错误 ') ;
end;
memo1.Lines.Add('[' + datetimetostr(now) + '] ' + '写文件 '+inttostr(ReadCount)+' 字节 ') ;
end; finally
FreeAndNil(fStream);
memo1.Lines.Add('[' + datetimetostr(now) + '] ' + sWriteFront + '传送结束 ') ;
end;
End
finally
AThread.Connection.Disconnect;
end;
end;
客户端:function TfrmVersionUpgrade.AcceptFile(MyClient: TIdTCPClient; AWriteLn: string):Boolean;
var
aFileName: string;
ftmpStream : TFileStream;
aFileSize: Integer;
ReadCount: Integer;
Buff: array[0..1023*100] of Byte;
ExeAdd: string;
sWriteFront, sWriteBack: string; //传送命令的前3位 和 传送命令的后几位(具体的信息)
LenStr: Integer; //传送命令的总长度
begin
Result := False;
ExeAdd := ExtractFilePath(ParamStr(0));//ExtractFilePath(Application.ExeName);
MyClient.Host:= FrmLogin.ServerIP; //连接服务器的IP地址
MyClient.port:=5555 ; //连接服务器的端口 with MyClient do
begin
try
if not MyClient.Connected then
connect;
except
MyClient.Free;
ShowMessage('网络连接错误或者FTP服务器没有打开') ;
Exit;
end; if connected then
begin //begin2
try //try2
writeln(AWriteLn); sWriteFront := Copy(AWriteLn, 1, 3);
LenStr := Length(AWriteLn);
sWriteBack := Copy(AWriteLn, 4, LenStr - 3); if sWriteFront = 'WRT' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '发送信息给服务器,记录升级记录!')
else if sWriteFront = 'INF' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '发送用户基本信息到服务器')
else if sWriteFront = 'SUC' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '发送信息到服务器:版本升级成功!')
else
begin //begin1 try //try1
if sWriteFront <> 'ILG' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '下载'+ AWriteLn + '指令已经发送'); aFileName := MyClient.ReadLn(#13#10, 100) ;
if aFileName = '' then Exit;
if FileExists(ExtractFilePath(ParamStr(0)) + '版本升级包\' + aFileName) then
begin
if sWriteFront <> 'ILG' then
memo1.Lines.Add('本地目录存在'+aFileName+',删掉这个文件');
DeleteFile(ExtractFilePath(ParamStr(0)) + '版本升级包\'+aFileName);
end;
MyClient.WriteLn;
MyClient.ReadBuffer(aFileSize, 4);
if sWriteFront = 'VSN' then
begin
ProgressBar1.Visible := True;
ProgressBar1.Max := aFileSize;
end;
ftmpStream:= TFileStream.Create(ExtractFilePath(ParamStr(0)) + '版本升级包\' + aFileName, fmCreate);
if sWriteFront <> 'ILG' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '正在写入' + AWriteLn + '文件......') ; repeat
if aFileSize - ftmpStream.Size > SizeOf(Buff) then
ReadCount := SizeOf(Buff)
else
ReadCount := aFileSize - ftmpStream.Size;
MyClient.ReadBuffer(Buff, ReadCount);
ftmpStream.WriteBuffer(Buff, ReadCount);
if sWriteFront = 'VSN' then
ProgressBar1.Position := ftmpStream.Size;
Application.ProcessMessages;
until ftmpStream.Size >= aFileSize;
if sWriteFront <> 'ILG' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '读取数据,写入数据!');
if sWriteFront = 'VSN' then
begin
ProgressBar1.Visible := False;
end;
finally
FreeAndNil(fTmpStream);
if sWriteFront <> 'ILG' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '释放文件流对象占用的资源');
end; //end try1 end; //end begin1
finally
disconnect;
MyClient.Free;
end; //end try2
end; //end begin2
end; //end with
Result := True;
end;
单个客户端是可行的,但是几个客户同时向服务器要同一文件包的时候就只能传一个了。服务器代码如下:大家帮我看看,应该怎么修改??
服务端://AwriteLn为客户端发送的内容,服务器端接到发送的内容会作出不同的回应
//AwriteLn = ILG + INI名称 FrmLogin调用,此窗口没有MEMO,ProgressBar1控件,
//AwriteLn = INI + INI名称 发送信息,让服务器传输 HPC_Version.INI的文本到本地
//AwriteLn = VSN + 版本号 发送信息,让服务器传输 该版本号的所有升级文件到本地
//AwriteLn = INF + 基本信息 发送用户信息,用户名+ 用户IP,中间用-隔开
//AwriteLn = SUC + 基本信息 发送到服务器,版本升级成功!
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
fStream : TFileStream;
aSize:integer;
Buf : array[0..1023*100] of Byte;
ReadCount: integer;
PathDir: string; //服务器升级文件存放的目录
s, sWriteFront, sWriteBack: string; //传送命令和 传送命令的前3位 和 传送命令的后几位(具体的信息)
sCom: string; //文件命令
LenStr, i, j, k: Integer; //传送命令的总长度
UserName, UserIP, Version: string; //传送过来的用户名和用户的本地IP
begin
PathDir := 'D:\DMS系统自动升级\' ;
try
s := uppercase(AThread.Connection.ReadLn);
sWriteFront := Copy(s, 1, 3);
LenStr := Length(s);
sWriteBack := Copy(s, 4, LenStr - 3); //根据客户端发送过来的命令,服务器发送相关的文件
if sWriteFront = 'INI' then sCom := '传送INI文本';
if sWriteFront = 'VSN' then
begin
sCom := sWriteBack + '传送版本数据';
PathDir := PathDir + 'DMS_HPC\'; //直接到 DMS_HPC 版本
end; if (sWriteFront = 'INF') then
begin
i := pos('-', s);
j := pos('#', s);
UserName := Copy(s, 4, i-4);
UserIP := Copy(s, i+1, j-i-1 );
Version := Copy(s, j+1, LenStr-j);
memo1.Lines.Add('[' + datetimetostr(now) + '] '
+ '用户:' + UserName + ' IP:'+UserIp
+ ' ' + Version +' 开始升级系统!') ;
CreateText( 'D:\DMS系统自动升级\HPC升级记录.txt', '[' + datetimetostr(now)+'] '
+ '用户:' + UserName + ' IP:' + UserIp + ' ' + Version + ' 开始升级系统!') ;
end; if sWriteFront = 'SUC' then
begin
memo1.Lines.Add('['+datetimetostr(now)+'] '+'接到指令' + sWriteFront + sCom) ;
CreateText( 'D:\DMS系统自动升级\HPC升级记录.txt', '[' + datetimetostr(now) + '] ' + sWriteBack) ;
end; if (sWriteFront = 'INI') or (sWriteFront = 'VSN') or (sWriteFront = 'ILG')then
Begin
try
if (sWriteFront = 'INI') or (sWriteFront = 'ILG') then //设置发送的类型
sWriteBack := sWriteBack + '.ini'
else
sWriteBack := sWriteBack + '.rar'; memo1.Lines.Add('[' + datetimetostr(now) + '] ' +'接到指令' + sWriteFront + sCom) ;
fstream:=tfilestream.Create(PathDir + sWriteBack, fmOpenRead + fmShareDenyNone);
AThread.Connection.WriteLn(ExtractFileName(sWriteBack));
AThread.Connection.ReadLn(#13#10, 1000) ; //多客户端时此报错
aSize:= fstream.Size;
AThread.Connection.WriteBuffer(aSize, 4);
memo1.Lines.Add( '[' + datetimetostr(now) + '] ' + '传送' + sWriteFront + '文件') ;
while fstream.Position < fstream.Size do
begin
if fstream.Size - fstream.Position >= SizeOf(Buf) then
ReadCount := sizeOf(Buf)
else ReadCount := fstream.Size - fstream.Position;
fstream.ReadBuffer(Buf, ReadCount);
try
AThread.Connection.WriteBuffer(Buf, ReadCount);
except
memo1.Lines.Add('AThread.Connection.WriteBuffer(Buf, ReadCount)'+' 错误 ') ;
end;
memo1.Lines.Add('[' + datetimetostr(now) + '] ' + '写文件 '+inttostr(ReadCount)+' 字节 ') ;
end; finally
FreeAndNil(fStream);
memo1.Lines.Add('[' + datetimetostr(now) + '] ' + sWriteFront + '传送结束 ') ;
end;
End
finally
AThread.Connection.Disconnect;
end;
end;
客户端:function TfrmVersionUpgrade.AcceptFile(MyClient: TIdTCPClient; AWriteLn: string):Boolean;
var
aFileName: string;
ftmpStream : TFileStream;
aFileSize: Integer;
ReadCount: Integer;
Buff: array[0..1023*100] of Byte;
ExeAdd: string;
sWriteFront, sWriteBack: string; //传送命令的前3位 和 传送命令的后几位(具体的信息)
LenStr: Integer; //传送命令的总长度
begin
Result := False;
ExeAdd := ExtractFilePath(ParamStr(0));//ExtractFilePath(Application.ExeName);
MyClient.Host:= FrmLogin.ServerIP; //连接服务器的IP地址
MyClient.port:=5555 ; //连接服务器的端口 with MyClient do
begin
try
if not MyClient.Connected then
connect;
except
MyClient.Free;
ShowMessage('网络连接错误或者FTP服务器没有打开') ;
Exit;
end; if connected then
begin //begin2
try //try2
writeln(AWriteLn); sWriteFront := Copy(AWriteLn, 1, 3);
LenStr := Length(AWriteLn);
sWriteBack := Copy(AWriteLn, 4, LenStr - 3); if sWriteFront = 'WRT' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '发送信息给服务器,记录升级记录!')
else if sWriteFront = 'INF' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '发送用户基本信息到服务器')
else if sWriteFront = 'SUC' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '发送信息到服务器:版本升级成功!')
else
begin //begin1 try //try1
if sWriteFront <> 'ILG' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '下载'+ AWriteLn + '指令已经发送'); aFileName := MyClient.ReadLn(#13#10, 100) ;
if aFileName = '' then Exit;
if FileExists(ExtractFilePath(ParamStr(0)) + '版本升级包\' + aFileName) then
begin
if sWriteFront <> 'ILG' then
memo1.Lines.Add('本地目录存在'+aFileName+',删掉这个文件');
DeleteFile(ExtractFilePath(ParamStr(0)) + '版本升级包\'+aFileName);
end;
MyClient.WriteLn;
MyClient.ReadBuffer(aFileSize, 4);
if sWriteFront = 'VSN' then
begin
ProgressBar1.Visible := True;
ProgressBar1.Max := aFileSize;
end;
ftmpStream:= TFileStream.Create(ExtractFilePath(ParamStr(0)) + '版本升级包\' + aFileName, fmCreate);
if sWriteFront <> 'ILG' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '正在写入' + AWriteLn + '文件......') ; repeat
if aFileSize - ftmpStream.Size > SizeOf(Buff) then
ReadCount := SizeOf(Buff)
else
ReadCount := aFileSize - ftmpStream.Size;
MyClient.ReadBuffer(Buff, ReadCount);
ftmpStream.WriteBuffer(Buff, ReadCount);
if sWriteFront = 'VSN' then
ProgressBar1.Position := ftmpStream.Size;
Application.ProcessMessages;
until ftmpStream.Size >= aFileSize;
if sWriteFront <> 'ILG' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '读取数据,写入数据!');
if sWriteFront = 'VSN' then
begin
ProgressBar1.Visible := False;
end;
finally
FreeAndNil(fTmpStream);
if sWriteFront <> 'ILG' then
memo1.Lines.Add('['+datetimetostr(now())+']' + '释放文件流对象占用的资源');
end; //end try1 end; //end begin1
finally
disconnect;
MyClient.Free;
end; //end try2
end; //end begin2
end; //end with
Result := True;
end;
2,客户端中的
aFileName := MyClient.ReadLn(#13#10, 100) ; 改成aFileName := MyClient.ReadLn();
因为原来的这个在0.1秒的情况中可能在服务器还没有传送完毕的时候就读下去了。所以服务器的那行才会报错。