文件传输问题?(100分)

  • 主题发起人 主题发起人 lisa_lqq
  • 开始时间 开始时间
L

lisa_lqq

Unregistered / Unconfirmed
GUEST, unregistred user!
我想做一个局域网内部的文件传输,代码如下,思路应该没错,可是就是不成功,哪位大虾帮忙看看?

服务端程序:
procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);
var
sRecv: string;

begin
sRecv := Socket.ReceiveText;
case sRecv[1] of
MP_REFUSE: ShowMessage('Faint,be refused!');
MP_ACCEPT:
begin
fsSend := TFileStream.Create(opendialog1.FileName, fmOpenRead);
//iBYTEPERSEND是个常量,每次发送包的大小。
Socket.SendText(MP_FILEPROPERTY + inttostr(Trunc(fsSend.Size / iBYTEPERSEND) + 1));

end;
MP_NEXTWILLBEDATA:
begin
Socket.SendText(MP_NEXTWILLBEDATA);
end;
MP_DATA:
begin
try
GetMem(bufSend, iBYTEPERSEND + 1);
if (fsSend.Position + 1 + iBYTEPERSEND) < fsSend.Size then
begin
fsSend.Read(bufSend^, iBYTEPERSEND);
Socket.SendBuf(bufSend^, iBYTEPERSEND);
// fsSend.Free;
end //普通的发送,大小为iBYTEPERSEND
else
begin
fsSend.Read(bufSend^, fsSend.Size - fsSend.Position - 1);
Socket.SendBuf(bufSend^, fsSend.Size - fsSend.Position - 1);
end; //最后一次发送,发送剩余的数据
finally
FreeMem(bufSend, iBYTEPERSEND + 1);
end; {of try}
end;
MP_ABORT:
begin
//被取消了:(
fsSend.Free;
end;
end;
客户端程序:
procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
sTemp: string;
bufRecv: Pointer;
iRecvLength,times,posx: integer;
begin
posx:=0;
if bReadText then
begin
sTemp := Socket.ReceiveText;
case sTemp[1] of
MP_QUERY:
begin
//在这里拒绝
SaveDialog1.FileName := Copy(sTemp, 2, Length(STemp));
if SaveDialog1.Execute then
begin
Socket.SendText(MP_ACCEPT);
fsRecv := TFileStream.Create(SaveDialog1.FileName, fmCreate);
end
else
Socket.SendText(MP_REFUSE + '去死');
end;
MP_FILEPROPERTY:
begin
//要发送StrToInt(Copy(sTemp,2,Length(sTemp))) 次
//时间进度显示。。。
times:=strtoint(copy(sTemp,2,length(sTemp)));
progressbar1.Max:=times;
progressbar1.Min:=0;
posx:=posx+1;
progressbar1.Position:=posx;
Socket.SendText(MP_NEXTWILLBEDATA);
end;
MP_NEXTWILLBEDATA:
begin
Socket.SendText(MP_DATA);
bReadText := false;

end;
MP_END:
begin
fsRecv.Free;
bReadText := true;
end;
MP_ABORT:
begin
fsRecv.Free;
bReadText := true;
end;
MP_CHAT:
begin
//Chat Msg
end;
end; {of case}
end
else
begin
try
GetMem(bufRecv, 2000); //2000 must >iBYTESEND
iRecvLength:=iBYTEPERSEND;
Socket.ReceiveBuf(bufRecv^, iRecvLength);
fsRecv.WriteBuffer(bufRecv^, iRecvLength);
finally
FreeMem(bufRecv, 2000);
end; {of try}
bReadText := true;
Socket.SendText(MP_NEXTWILLBEDATA);
end;

end;
 
demo里有现成的NMStrm的例子,用UDP也可以,都很简单
 
把你用动态内存分配都改成数组缓冲试试:
即定义个数Buffer:array[1..100000]of char;
我一般都不用动态分配,那样麻烦又易出错!
 
不过哪个例子不能使用过大的文件。
 
有一点不太明白,你为什么在Server和Client都是先Socket.ReceiveText呢
按照你的协议,好像应该先Send一个什么到Server,然后再Receive。[?]
 
to tseug:因为要判断是否愿意接收啊?
to jauan:有没有更好的办法呢,这个方法,试了很久都没有成功。
 
to lisa_lqq 这么久了,不知道你的问题解决了没有,我试过你的方法,发现只是在传到最后部分,就是剩下部分小于iBytePerSend时传输出错,好像这一部分传输的大小为0。如果你已经解决了,请通知我一下,谢谢!!!ewgh@etang.com
 
后退
顶部