idtcpserver传输文件的问题,请高手解答,谢谢..(50分)

T

tl_lyq

Unregistered / Unconfirmed
GUEST, unregistred user!
我做的即时通信程序,发送信息通过udp实现,发送文件时,采用udp进行文件名称,大小的通知,用tcpserver tcpclient 做文件的传输,
客户端发文件时先发给服务器,由服务器先通过udp 通知某客户端有文件待接收,
客户接收时, 动态创建tcpclient,连接服务端的tcpserver,给出待传送的文件名,大小,服务端的tcpserver与客户端的tcpcient建立连接,并取出相应的文件,开始发送给客户端,
如果客户收到多个文件,如何在线程里创建tcpclient呢,
还有,现在服务端tcpserver如果同时给多个客户端传文件,好象传完最后一个文件后,才开始传前一个文件,不是同步传输的..请高手指教.
 
//客户端
//客户端收到接收文件的通知,自动创建idtcpclient,并主动与服务器的idtcpserver发起连接,接收服务端响应的文件
procedure TForm1.Button1Click(Sender: TObject);
var
ASize, TotalSize: Int64;
AFileStream: TFileStream;
idtcpclient1:tidtcpclient;
begin
try
idtcpclient1:=tidtcpclient.Create(self);
IdTCPClient1.Host :='127.0.0.1';
IdTCPClient1.Port := 5020;
IdTCPClient1.Connect;
IdTCPClient1.WriteLn('begin
'+'msde.rar');
TotalSize := 27560992;
AFileStream := TFileStream.Create('C:/'+'msde.rar', fmCreate);
try
repeat
IdTCPClient1.WriteLn(IntToStr(AFileStream.Size));
ASize := Min(TotalSize - AFileStream.Size, IdTCPClient1.RecvBufferSize);
IdTCPClient1.ReadStream(AFileStream, ASize);
StatusBar1.SimpleText := Format('当前传输位置%d/大小%d', [AFileStream.Size, TotalSize]);
Application.ProcessMessages;
until AFileStream.Size = TotalSize;
finally
AFileStream.Free;
end;
IdTCPClient1.WriteLn('END');
StatusBar1.SimpleText := '传输完成...';
IdTCPClient1.Disconnect;
idtcpclient1.Free;
except
StatusBar1.SimpleText := '连接服务器失败或者对方已经中断传输!';
end;
end;
 
//服务端
unit s;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPServer, StdCtrls, ComCtrls,math,
IdAntiFreezeBase, IdAntiFreeze, ExtCtrls;
type
TForm1 = class(TForm)
IdTCPServer1: TIdTCPServer;
StatusBar1: TStatusBar;
IdAntiFreeze1: TIdAntiFreeze;
ListView1: TListView;
procedure IdTCPServer1Execute(AThread: TIdPeerThread);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);

private
AFileStream: TFileStream;
{ Private declarations }
public
{ Public declarations }
end;
type
TSimpleClient = Record
id: longint;
FileName: string;
Filesize: integer;
Sendsize: integer;
IP: string;
Port: integer;
end;
PClient = ^TSimpleClient;
var
Form1: TForm1;
implementation
{$R *.dfm}

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
cmd: string;
ASize: Integer;
Client: PClient;
i,index:integer;
begin
with AThread.Connectiondo
begin
athread.Synchronize;
Client := Pointer(AThread.Data);
index:=-1;
for i:=0 to listview1.Items.Count -1do
if strtoint(listview1.items.SubItems [4])=client.id then
index:=i;
cmd := UpperCase(ReadLn);
if copy(cmd,0,5) = 'begin
' then
begin
AFileStream := TFileStream.Create('E:/'+copy(cmd,6,100), fmOpenRead);
Client.FileName := copy(cmd,6,100);
Client.FileSize := AFileStream.Size;
listview1.Items[index].caption:=client.FileName;
listview1.Items[index].subitems[0]:=client.IP ;
listview1.Items[index].subitems[1]:=inttostr(client.port);
listview1.Items[index].subitems[2]:=formatfloat('0.000',(AFileStream.Size /1024 / 1024))+'M';
Exit;
end;
if cmd = 'END' then
begin
listview1.Items[index].Delete;
Exit;
end;
if cmd = 'CANCEL' then
begin
listview1.items[index].Delete;
Exit;
end;
AFileStream.Seek(StrToInT(cmd), soFrombegin
ning);
ASize := Min(AFileStream.Size - AFileStream.Position, RecvBufferSize);
OpenWriteBuffer;
WriteStream(AFileStream, false, false, ASize);
Client.SendSize := strtoint(cmd);
CloseWriteBuffer;
try listview1.Items[index].SubItems[3]:=formatfloat('0%',strtofloat(cmd) / client.filesize *100);except end;
end;
end;

procedure TForm1.FormClose(Sender: TObject;
var Action: TCloseAction);
begin

IdTCPServer1.Active := False;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if not IdTCPServer1.Active then
IdTCPServer1.Active := True;
end;

procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
var Client: PClient;
begin
Client := new( PClient );
Client.id := listview1.Items.Count+1 ;
Client.FileName := '';
Client.FileSize := 0;
Client.SendSize := 0;
Client.IP := AThread.Connection.Socket.Binding.PeerIP;
Client.Port := AThread.Connection.Socket.Binding.PeerPort;
AThread.Data := Pointer(client );
with listview1.items.Adddo
begin
caption:='';
subitems.add('');
subitems.add('');
subitems.add('');
subitems.add('');
subitems.add(inttostr(client.id));
end;
end;

procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
var Client: PClient;
begin
Client := Pointer(AThread.Data);
AThread.Data := nil;
end;

end.
 
先谢谢 了,我的QQ 244812585
 
顶部