我用IdTCPClient传输文件后,文件在大小是一模一样的,但是传过的文件就是无法执行,用fc比较了一下有很多地方不一样。但传的文本文件却打开正常,但用fc比较还是不行,代码如下:客户端:
procedure TForm1.Button2Click(Sender: TObject);
var
answer:string;
MS:TMemoryStream;
block:int64;
i:integer;
buff:PByteArray ;
lastblock:integer;
blocksize:int64;
fs:TFileStream;
begin
blocksize:=8000;
tc.Host:='192.168.0.16';
tc.Port:=1217;
tc.Connect;
tc.WriteLn('UPFILE');
Answer:=tc.ReadLn;
if Answer='YES' then
begin
fs:=TFileStream.Create(e1.Text,fmOpenRead); if fs.Size>blocksize then
begin
block:=trunc(fs.Size/blocksize);
lastblock:=fs.Size-block*blocksize;
end
else begin
block:=0;
blocksize:=fs.Size;
end;
tc.WriteInteger(blocksize);
tc.WriteInteger(lastblock);
tc.writeinteger(block);
for i:=0 to block-1 do
begin
tc.WriteLn('NEXT');
tc.WriteStream(fs,true,false,blocksize);
end;//for;
if block<>0 then
begin
tc.WriteLn('LAST');
tc.WriteStream(fs,true,false,lastblock);
end;
tc.WriteLn('FINISH'); tc.Disconnect;
fs.Free;
end
end;
服务器端
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
msg:string;
fs:tfilestream;
buff:PByteArray ;
blocksize:int64;
lastblocksize:int64;
blockcount:int64;
i:integer;
begin
msg:=Athread.Connection.ReadLn;
if MSG='UPFILE' then
begin
athread.Connection.WriteLn('YES'); blocksize:=ATHREAD.Connection.ReadInteger; lastblocksize:=athread.Connection.ReadInteger; blockcount:=athread.Connection.ReadInteger();
fs:=tfilestream.Create('d:\wpf.mp3',fmCreate);
for i:=0 to blockcount-1 do
begin
Msg:=athread.Connection.ReadLn;
if msg='NEXT' then
athread.Connection.ReadStream(fs,blocksize);
msg:='';
end;//for if blockcount<>0 then
begin
msg:=athread.Connection.ReadLn;
if msg='LAST' then
athread.Connection.ReadStream(fs,lastblocksize);
end;
msg:=athread.Connection.ReadLn;
if msg='FINISH' then athread.Connection.Disconnect;
fs.Free;
end;
end;我感觉可能是同步有问题,但从代码上我又发现不到同步问题,还望大家帮忙。
procedure TForm1.Button2Click(Sender: TObject);
var
answer:string;
MS:TMemoryStream;
block:int64;
i:integer;
buff:PByteArray ;
lastblock:integer;
blocksize:int64;
fs:TFileStream;
begin
blocksize:=8000;
tc.Host:='192.168.0.16';
tc.Port:=1217;
tc.Connect;
tc.WriteLn('UPFILE');
Answer:=tc.ReadLn;
if Answer='YES' then
begin
fs:=TFileStream.Create(e1.Text,fmOpenRead); if fs.Size>blocksize then
begin
block:=trunc(fs.Size/blocksize);
lastblock:=fs.Size-block*blocksize;
end
else begin
block:=0;
blocksize:=fs.Size;
end;
tc.WriteInteger(blocksize);
tc.WriteInteger(lastblock);
tc.writeinteger(block);
for i:=0 to block-1 do
begin
tc.WriteLn('NEXT');
tc.WriteStream(fs,true,false,blocksize);
end;//for;
if block<>0 then
begin
tc.WriteLn('LAST');
tc.WriteStream(fs,true,false,lastblock);
end;
tc.WriteLn('FINISH'); tc.Disconnect;
fs.Free;
end
end;
服务器端
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
msg:string;
fs:tfilestream;
buff:PByteArray ;
blocksize:int64;
lastblocksize:int64;
blockcount:int64;
i:integer;
begin
msg:=Athread.Connection.ReadLn;
if MSG='UPFILE' then
begin
athread.Connection.WriteLn('YES'); blocksize:=ATHREAD.Connection.ReadInteger; lastblocksize:=athread.Connection.ReadInteger; blockcount:=athread.Connection.ReadInteger();
fs:=tfilestream.Create('d:\wpf.mp3',fmCreate);
for i:=0 to blockcount-1 do
begin
Msg:=athread.Connection.ReadLn;
if msg='NEXT' then
athread.Connection.ReadStream(fs,blocksize);
msg:='';
end;//for if blockcount<>0 then
begin
msg:=athread.Connection.ReadLn;
if msg='LAST' then
athread.Connection.ReadStream(fs,lastblocksize);
end;
msg:=athread.Connection.ReadLn;
if msg='FINISH' then athread.Connection.Disconnect;
fs.Free;
end;
end;我感觉可能是同步有问题,但从代码上我又发现不到同步问题,还望大家帮忙。
tc.WriteLn('UPFILE');
Answer:=tc.ReadLn;
if Answer='YES' then
begin
fs:=TFileStream.Create(e1.Text,fmOpenRead);
tc.WriteInteger( fs.Size );
tc.WriteStream( fs, fs.Size );
fs.Free;
end;
tc.Disconnect;server:
msg:=Athread.Connection.ReadLn;
if MSG='UPFILE' then
begin
athread.Connection.WriteLn('YES'); size:=ATHREAD.Connection.ReadInteger;
fs:=tfilestream.Create('d:\wpf.mp3',fmCreate);
athread.Connection.ReadStream(fs,size);
fs.Free;
AThread.Connection.Disconnect;
end;
Client的发送块顺序:1、2、3、4、5
Server的接收块顺序(可能):1、2、4、5、3
那么你的文件在拼接时肯定是不对的(你在服务器代码里用了For,这是没有顺序的)
你可以为你的块建个Record的数据结构,其中添上块的顺序信息,然后发送;服务器端根据块顺序拼接。