SOCKET点到点传文件,有真正做过实用程序的高手吗?急!(200分)

  • 主题发起人 主题发起人 yuzhou
  • 开始时间 开始时间
Y

yuzhou

Unregistered / Unconfirmed
GUEST, unregistred user!
要求是这样的:用MODEM连接两台机器,客户端传一个文件到服务端,服务端对数据检查
后立刻把检查结果返回给客户端。用TClientSocket和TServerSocket。
发送方(客户端)发起一个SOCKET连接,连接成功后把文件读入TFileStream。先把文件
名和大小发出去。ClientSocket1.Socket.SendText(FileSize1+','+FileName1);
收到服务端响应后,再把文件流发出去。
ClientSocket1.Socket.SendStream(Stream1);
接收方(服务端)收到文件名,大小,先根据文件名创建一个文件流,再把收到的数据放
入流中。文件可能较大,(2M)所以肯定要多次接收数据包。我把服务端OnRead的代码贴
上来。
procedure TFmMain.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
Stream1 : TFileStream;
MyReceviceLength : Integer;
Str : String;
MyBuffer: array[0..10000] of byte; {设置接收缓冲区}
begin
if (FileSize1 = 0) then //根据FileSize1判断收到的是文件名还是数据
begin
Str := Socket.ReceiveText;
FileSize1 := Strtoint(Copy(Str,1,pos(',',Str)-1));
FileName1 := Copy(Str, pos(',',Str)+1, Length(Str)-pos(',',Str));
Stream1 := TFileStream.Create(FilePath+'/'+FileName1,fmCreate);//创建接收流
Stream1.Position :=0;
ServerSocket1.Socket.Connections[0].SendText('ready');//响应客户端
end
else
begin
MyReceviceLength := socket.ReceiveLength; {读出包长度}
Socket.ReceiveBuf(MyBuffer, MyReceviceLength); {接收数据包并读入缓冲区内}
Stream1.Write(MyBuffer, MyReceviceLength); {将数据写入流中} //注意,在这里出错
if Stream1.Size >= FileSize1 then
begin
ServerSocket1.Socket.Connections[0].SendText('fileok');
Stream1.Free;
FileSize1 := 0;
ServerSocket1.Socket.Connections[0].Disconnect(0);
end;
end;
end;

现在有这样的错误:把数据写入流中时,报Access Violation。(我曾经改用内存流,同
样的错)上面这段程序曾经正常运行了三四天,传送文件没有问题。现在搞的我很郁闷。
哪位高手可以解决这个问题,300分双手奉上。或者不用SOCKET用其他的方法,只要能保
证绝对稳定运行。(将来还要加上多个客户端并发传送的功能,请考虑这一点)可以直接
和我联系,交个朋友。rainbow30@263.net
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=730014
 
你出错的直接表面原因是
Stream1.Write(MyBuffer, MyReceviceLength); {将数据写入流中} //注意,在这里出错
中的STREAM1没有CREATE
更深层次的原因是你的STREAM1居然是一个局部变量,至少我想该是一个类中的PRIVATE方法吧,
这样导致了你的传输文件无法超过 8K/16K/32K/64K ,这是SOCKET的默认缓冲区
考虑到多个客户端传输,至少你该为每个链接创建一个TFILESTREAM,可以使用一个
TFILESTREAM数组或者用TLIST来管理
 
to wenyue:
我把STREAM设为全局,问题解决了。
再请教:用这种方法稳定吗?如果用NMFTP,相比较而言,哪个更好?
 
个人认为SOCKET写要好写,用FTP又会出现有一些权限方面的控制问题,还需要用户名登陆
我认为你的方法其实是可行而且可靠.

当然这看个人的经验了,如果经验不足够解决SOCKET中可能遇到的问题,
使用现成的组件会更可靠.
 
to wenyue;
多谢。我对你的崇拜犹如滔滔……,交个朋友如何?
 
后退
顶部