点对点发送文件的程序中出现的问题!网络高手,快帮我!(100分)

梨皮

Unregistered / Unconfirmed
GUEST, unregistred user!
我看了zou5655写的点对点传送文件的文挡后,自己做试着做了一个~!但是却出现了一个问题,文件发送后弹出一个对话框,提示:'floating point division by zero!'并且接收到的文件大小都为0,如果有哪为/位高手愿意指点一二,大分酬谢!
程序可谓服务端也可为客户端,
协议:
首先由Client发送MP_QUERY,Server接受到后发送MP_ACCEPT或MP_FEFUESE;
Client接受到MP_ACCEPT发送MP_FILEPROPERTY,Server接受到后发送MP_NEXTWILLBEDATA;
Client接受到发送MP_NEXTWILLBEDATA,Server接受到后发送MP_DATA;
Client接受到MP_DATA,发送数据,Server接受数据,并发送MP_NEXTWILLBEDATA;
循环,直到Client发送MP_OVER;
中间可以互相发送MP_CHAT+String;
--------------------------------------------------------
unit Client;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ScktComp, ComCtrls;
Const
MP_QUERY ='1';
MP_REFUSE ='2';
MP_ACCEPT ='3';
MP_NEXTWILLBEDATA='4';
MP_DATA ='5';
MP_ABORT ='6';
MP_OVER ='7';
MP_CHAT ='8';
MP_FILEPROPERTY='9';
MP_END='0';


type
TForm1 = class(TForm)
edtIPAddress: TEdit;
btnConnect: TBitBtn;
btnSendFile: TBitBtn;
OpenDialog1: TOpenDialog;
cs: TClientSocket;
btnStartServer: TBitBtn;
BitBtn1: TBitBtn;
ss: TServerSocket;
SaveDialog1: TSaveDialog;
StatusBar1: TStatusBar;
procedure btnConnectClick(Sender: TObject);
procedure btnSendFileClick(Sender: TObject);
procedure csRead(Sender: TObject; Socket: TCustomWinSocket);
procedure csConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure csConnecting(Sender: TObject; Socket: TCustomWinSocket);
procedure csDisconnect(Sender: TObject; Socket: TCustomWinSocket);
procedure btnStartServerClick(Sender: TObject);
procedure ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
procedure BitBtn1Click(Sender: TObject);
procedure ssClientConnect(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnConnectClick(Sender: TObject);
begin
try
cs.Address:=edtIPAddress.Text;
cs.Port:=2000;
cs.Open;
finally
StatusBar1.Panels[0].Text:='连接发生错误!';
end;
end;

procedure TForm1.btnSendFileClick(Sender: TObject);
begin
if opendialog1.Execute then
begin
cs.Socket.SendText(MP_QUERY+opendialog1.FileName);
end;
end;
procedure TForm1.csRead(Sender: TObject; Socket: TCustomWinSocket);
var
fssend:TfileStream;
MP_FILEPROPERTY:string;
iBYTEPERSEND:integer;
sTemp:string;
bufsend:pointer;
srecv:string;
begin

srecv:=socket.ReceiveText;
case sRecv[1] of
MP_REFUSE:showmessage('对方叫你去死!');
MP_ACCEPT:begin
fsSend:=TFileStream.Create(OpenDialog1.FileName,fmOpenReadWrite);
form1.StatusBar1.Panels[1].Text:='发送文件大小:'+inttostr(fssend.Size);
//iBYTEPERSEND是个常量,每次发送包的大小。
Socket.SendText(MP_FILEPROPERTY+inttostr(Trunc(fsSend.Size/iBYTEPERSEND)+1));
//statusbar1.Panels[0].Text:= 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
else begin
fsSend.Read(bufSend^,fsSend.Size-fsSend.Position-1);
Socket.SendBuf(bufSend^,fsSend.Size-fsSend.Position-1);

end;
socket.SendText(MP_over)
finally
freemem(bufsend,iBYTEPERSEND);

end;{of try}
end;
mp_abort:begin
showmessage('对方没有应答!')

end;
end;{of case}
end;

procedure TForm1.csConnect(Sender: TObject; Socket: TCustomWinSocket);
begin

StatusBar1.Panels[0].Text :='成功连接到对方计算机!';

end;

procedure TForm1.csConnecting(Sender: TObject; Socket: TCustomWinSocket);
begin

StatusBar1.Panels[0].Text:='正在连接到对方计算机…………';

end;

procedure TForm1.csDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
StatusBar1.Panels[0].Text :='对方下线!';
end;

procedure TForm1.btnStartServerClick(Sender: TObject);
begin
ss.Port:=2000;
ss.Open;
StatusBar1.Panels[0].Text :='当前状态:上线!';
end;

procedure TForm1.ssClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
fsRecv:Tfilestream;
sTemp:string;
bufRecv:pointer;
iRecvLength:integer;
breadtext:boolean;
begin
breadtext:=true;
if bReadText then
begin
sTemp:=Socket.ReceiveText;
case sTemp[1] of
MP_QUERY:begin

if MessageDlg('有文件到达,要接收吗?',mtConfirmation, [mbYes, mbNo], 0) = mrYes then
begin
SaveDialog1.FileName:=Copy(sTemp,2,Length(STemp));
if SaveDialog1.Execute then
begin
Socket.SendText(MP_ACCEPT);
fsRecv:=TFileStream.Create(SaveDialog1.FileName,fmCreate);
end;
end
else
socket.SendText(MP_REFUSE+'去死!');

end;

MP_FILEPROPERTY:begin
showmessage('StrToInt(Copy(sTemp,2,Length(sTemp)))');
//要发送StrToInt(Copy(sTemp,2,Length(sTemp))) 次
//时间进度显示。。。
Socket.SendText(MP_NEXTWILLBEDATA);
end;
MP_NEXTWILLBEDATA:begin
Socket.SendText(MP_DATA);
bReadText:=false;
end;
mp_over:begin
fsrecv.Free;
breadtext:=true;
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
Socket.ReceiveBuf(bufRecv^,iRecvLength);
fsRecv.WriteBuffer(bufRecv^,iRecvLength);
finally
FreeMem(bufRecv,2000);
end;{of try}
bReadText:=true;
Socket.SendText(MP_NEXTWILLBEDATA);
end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
ss.Close;
StatusBar1.Panels[0].Text :='当前状态:下线!';
end;

procedure TForm1.ssClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
StatusBar1.Panels[0].Text:='有人连上你了!';
end;

end.
--------------------
详细资料见http://labulle.net/membre/9li_nanze/books/list.asp?id=39
 
老兄,拜托你自己先追一下,这么长的代码怎么看
 
我把两个filestream变量设为全局后,没有错误发生,并给iRecvLength,iBYTEPERSEND赋值,就没有错误发生,但是接收到的文件长度只有0k!
是怎么回事?
帮个忙!谢谢!
 
找我把,QQ 775033,我发送200M多的文件都没有问题
 
接受部分
procedure TForm1.ClientSocket2Read(Sender: TObject;
Socket: TCustomWinSocket);
var len:integer;
temp:string;
begin
if stStatue=stgetFile then
begin
Len:=Socket.ReceiveLength;
Temp:=Socket.ReceiveText;
filem.Write(PChar(Temp)^,len); //filem是一个文件流
inc(allLen,len);
if allLen=getfilesize then //allLen是文件长度,你先传送过来
ShowMessage('文件接受完毕!');
end;

发送部分
const
MAX_LEN=2048;

var
iSen:integer; //iSen发送出去的长度
iSize:integer; //文件长度 最好是全局变量
buf:array[1..MAXLEN]of char;
senlen:integer; //每次应该发送的长度
ret:integer; //实际发送的文件长度
filen:TFileStream; //最好是全局变量

iSen:=0;
while iSen<iSize do
begin
FillChar(buf,MAX_LEN,0);
if iSize-iSen>MAX_LEN then senlen:=MAX_LEN
else senLen:=iSize-iSen;
filen.Position:=iSen;
filen.Read(buf,senLen);
ret:=ClientSocket1.Socket.SendBuf(buf,senLen);
inc(iSen,ret);
end;
 
接受答案了.
 
顶部