请问用socket传输文件,文件大小有没有限制?(100分)

  • 主题发起人 主题发起人 guan1573
  • 开始时间 开始时间
G

guan1573

Unregistered / Unconfirmed
GUEST, unregistred user!
请问用socket传输文件,文件大小有没有限制?
速度会不会很慢?
怎么样实现断点续传?
 
大小没有限制的,但文件传送需要分成一个个小包来进行转输,最好2K-4K之间。速度不慢啊。
 
楼上说得对,只要你的硬盘空间足够,不论多大的文件都可传输,但最好分批传输,每次
1~2KB,否则会使系统反应不过来(会假死几秒钟)。
另外,要用到文件流。我以前做过一个例子。
 
没有限制的
它是采用流式传送的
 
怎样将文件分成一个个的小包?就是在程序里读取文件流时,一点点的读取吗?
 
to zfs88
能否给我你的例子?不能也没有关系,谢谢!!
 
to guan1573:以下是源代码。为取得客户端的IP,我还用了UDP广播。(好用的话记得给我加分哦 -:)
服务端:
procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Open; //开始侦听客户端的连接请求
EnumInterfaces(sIP,sMask); //获取IP地址及子网掩码
NMUDP1.RemoteHost:=GetBCIP(sIp,sMask);  //设置UDP的广播地址
end;
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
begin
Edit1.Text:=ExtractFileName(OpenDialog1.FileName);
FileSize:=GetFileSize(OpenDialog1.FileName);
fs:=TFilestream.Create(OpenDialog1.FileName,fmOpenRead);
Button1.Enabled:=true;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
DataStream:TMemoryStream;
begin
DataStream:=TMemoryStream.Create;
DataStream.Write(sIP[1],length(sIP));  //将服务端的IP地址广播出去
NMUDP1.SendStream(DataStream); //NMUDP1的RemoteHost设为广播地址:192.168.1.255
DataStream.Free;
Button1.Enabled:=false;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
s:string;
i:integer;
begin
s:=OpenDialog1.FileName+'/'+InttoStr(FileSize);
Button2.Enabled:=false;
for i:=0 to ServerSocket1.socket.ActiveConnections-1 do //首先发送文件名、文件大小信息
ServerSocket1.socket.Connections.sendbuf(s[1],length(s));
end;
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
const DataSize=1024;
var
ReTxt:string;
buff:pointer;
RealCount,i:integer;
begin
ReTxt:=socket.ReceiveText;
if ReTxt='Ready' then
begin  //开始发送文件
getmem(buff,datasize); //RealCoun为实际读取的字节数
RealCount:=fs.Read(buff^,datasize);
for i:=0 to ServerSocket1.socket.ActiveConnections-1 do  //向所有已建立连接的客户端分批发送文件内容
ServerSocket1.socket.Connections.sendbuf(buff^,RealCount);
freemem(buff,DataSize);
end;
end;

procedure TForm1.NMUDP1DataReceived(Sender: TComponent;
NumberBytes: Integer; FromIP: String);
var
Buff: string;
begin
setlength(Buff,NumberBytes);
NMUDP1.ReadBuffer(Buff[1],NumberBytes);
Memo1.Lines.Add(Buff);
Memo1.Lines.Add('客户端IP :'+FromIP);
Button2.Enabled:=true;
end;
end.

客户端:
var
Form1: TForm1;
FileName:string;
FileSize:integer;
DestFileStream:TFileStream;
FilenfoReceived:Boolean; //表示是否已接收到文件名及文件大小信息

implementation

{$R *.DFM}

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
const datasize=1024;
var RealCount:integer;
FileInfo:string;
Buff:Pointer;
begin
if (not FilenfoReceived) then
begin
FilenfoReceived:=true;
FileInfo:=socket.ReceiveText;
FileName:=copy(FileInfo,1,pos('/',FileInfo)-1); //服务端发送的文件名与文件长度之间有一“/”
Memo1.lines.add('文件名:'+FileName);
FileSize:=StrToInt(copy(FileInfo,pos('/',FileInfo)+1,length(FileInfo)));
Memo1.lines.add('文件大小:'+Inttostr(FileSize)+' Byte');
ClientSocket1.Socket.SendText('Ready');
ProgressBar1.Max:=filesize;
ProgressBar1.Step:=1;
//建立目标文件
DestFileStream:=TFileStream.Create(ExtractFileName(FileName),fmCreate or fmOpenWrite);
end
else
//开始接收文件
begin
getmem(buff,datasize);
RealCount:=ClientSocket1.Socket.ReceiveBuf(Buff^,datasize);
DestFileStream.WriteBuffer(Buff^,RealCount); //将接收到的文件内容写入目标文件
edit1.Text:='已接收:'+inttostr(DestFileStream.size)+'Byte';
ProgressBar1.Position:=DestFileStream.Size;
ClientSocket1.Socket.SendText('Ready'); //返回一条信息,准备接收后续数据
freemem(buff);
if DestFileStream.size>=FileSize then
begin
Memo1.Lines.Add('文件传输完毕!');
DestFileStream.Free;
end;
end;
end;
 
多人接受答案了。
 
后退
顶部