一传比较大的文件,比如5M以上的,就会发生数据接收不全,这是怎么回事服务端procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
C : PCON;
cmd:String;
Buffer : pointer;
nRetr : integer;
ReadCount : integer;
const
bufferSize = 1024 ;
begin
C:= Socket.Data ;
case c.Status of
0 :
begin
cmd := trim(Socket.ReceiveText) ;if Pos('UPLOAD ',uppercase(cmd)) > 0 then
begin
c.FileName := trim(Copy(cmd,Pos(' ',cmd)+1,Length(cmd)));
c.TotalSize := StrToInt(Copy(c.FileName,Pos(' ',c.FileName)+1,Length(c.FileName)));
c.FileName := trim(Copy(c.FileName,1,Pos(' ',c.FileName)));
c.Status := 1;
Socket.Data := C;
fs :=TFileStream.Create('data\'+c.FileName,fmCreate or fmShareDenyNone);
fs.Free;
// fs.Seek(0,soFromBeginning);
Socket.SendText('SEND');
end;
end;
1 : begin
inc(i);
GetMem(Buffer,BufferSize);
nRetr := Socket.ReceiveBuf(Buffer^,BufferSize);
if FIleExists('data\'+c.FileName) then
begin
fs :=TFileStream.Create('data\'+c.FileName,fmOpenWrite or fmShareDenyNone);
fs.Seek(0,soFromEnd);
end; fs.WriteBuffer(Buffer^,nRetr);
// fs.Destroy;
FreeMem(Buffer);
end;
end;end;
客户端
procedure TForm2.CSRead(Sender: TObject; Socket: TCustomWinSocket);
var
rlt : String;
fs : TFileStream;
Buf : pointer;
nRead : Integer;
m_bSending : boolean;
lBytesSent : longint;
i:integer;
begin
rlt := Socket.ReceiveText;
i:=0;
if rlt='SEND' then
begin
lBytesSent:=0;
m_bSending := TRUE;
fs := TFileStream.Create(c.FileName,fmOpenRead or fmShareDenyNone);
GetMem(Buf,fs.Size);
while m_bSending do
begin
inc(i);
if (fs.Seek(lBytesSent,soFromBeginning) = lBytesSent) then
begin
nRead := fs.Read(Buf^,1024);
try
Form2.ProgressBar1.Position := fs.Position;
Cs.Socket.SendBuf(Buf^,nRead);
except
end;
if nRead < 1024 then
begin
lBytesSent := lBytesSent + nRead;
m_bSending := false;
end
else
begin
// Sleep(2);
lBytesSent := lBytesSent + 1024;
end;
end
else
m_bSending := false;
end;//endwhile
end;//endif
fs.Destroy;
FreeMem(Buf);
showMessage(inttostr(i));
end;
Socket: TCustomWinSocket);
var
C : PCON;
cmd:String;
Buffer : pointer;
nRetr : integer;
ReadCount : integer;
const
bufferSize = 1024 ;
begin
C:= Socket.Data ;
case c.Status of
0 :
begin
cmd := trim(Socket.ReceiveText) ;if Pos('UPLOAD ',uppercase(cmd)) > 0 then
begin
c.FileName := trim(Copy(cmd,Pos(' ',cmd)+1,Length(cmd)));
c.TotalSize := StrToInt(Copy(c.FileName,Pos(' ',c.FileName)+1,Length(c.FileName)));
c.FileName := trim(Copy(c.FileName,1,Pos(' ',c.FileName)));
c.Status := 1;
Socket.Data := C;
fs :=TFileStream.Create('data\'+c.FileName,fmCreate or fmShareDenyNone);
fs.Free;
// fs.Seek(0,soFromBeginning);
Socket.SendText('SEND');
end;
end;
1 : begin
inc(i);
GetMem(Buffer,BufferSize);
nRetr := Socket.ReceiveBuf(Buffer^,BufferSize);
if FIleExists('data\'+c.FileName) then
begin
fs :=TFileStream.Create('data\'+c.FileName,fmOpenWrite or fmShareDenyNone);
fs.Seek(0,soFromEnd);
end; fs.WriteBuffer(Buffer^,nRetr);
// fs.Destroy;
FreeMem(Buffer);
end;
end;end;
客户端
procedure TForm2.CSRead(Sender: TObject; Socket: TCustomWinSocket);
var
rlt : String;
fs : TFileStream;
Buf : pointer;
nRead : Integer;
m_bSending : boolean;
lBytesSent : longint;
i:integer;
begin
rlt := Socket.ReceiveText;
i:=0;
if rlt='SEND' then
begin
lBytesSent:=0;
m_bSending := TRUE;
fs := TFileStream.Create(c.FileName,fmOpenRead or fmShareDenyNone);
GetMem(Buf,fs.Size);
while m_bSending do
begin
inc(i);
if (fs.Seek(lBytesSent,soFromBeginning) = lBytesSent) then
begin
nRead := fs.Read(Buf^,1024);
try
Form2.ProgressBar1.Position := fs.Position;
Cs.Socket.SendBuf(Buf^,nRead);
except
end;
if nRead < 1024 then
begin
lBytesSent := lBytesSent + nRead;
m_bSending := false;
end
else
begin
// Sleep(2);
lBytesSent := lBytesSent + 1024;
end;
end
else
m_bSending := false;
end;//endwhile
end;//endif
fs.Destroy;
FreeMem(Buf);
showMessage(inttostr(i));
end;
解决方案 »
- 36选7的算法一共有多少种选法
- DELPHI和金山快译出现的严重问题,送你十分,祝你身体十分健康,谢谢
- 一句SQL SERVER的SQL语句翻译成ACCESS的SQL语句的问题,内详!
- 大家进来谈谈,在用delphi时常用的快捷方式,以及在遇到问题时的解决途径,还有如何运用帮助文件
- VB转Delphi中的字符串操作问题
- 十万火急,如何高速打印,如何能在98下运行xp下做的qreport程序?
- 查询日期 ?
- 那里可以下载到delphi?
- 怎样检索某一FIELD中值不重复的记录?
- 如何复制一个表格(包括字段和记录)
- 怎么我的代码捕获不到异常呢?
- 救命!特急,哪位有“项目开发总结报告”,时间特紧,帮忙啊!
我不知道你的nread有没有可能小于1024,因为你每次都读1024长。
你可以自己分解每个包的长度,这样可以计算包的数量,每发送一个包,服务器端发回一个确认信息,这样才能够比较准确。
每发送一个包后,必须加上一定的延时,否则在internet传输时肯定丢数据。
服务器端缺少一个文件完整接收后复原的操作。
从结构上看除了以上问题看不出其它问题,不过你的data并不是传送文件的好方式,不要照套别人的代码。
[email protected]
[email protected]
[email protected]
//客户端
unit client;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls, ScktComp;type
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
OpenDialog1: TOpenDialog;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Memo1: TMemo;
ProgressBar2: TProgressBar;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ClientSocket1Connecting(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
function getfilename(str1:string):string;
private
{ Private declarations }
public
{ Public declarations }
end; type
FileInf=Record
name: String; //文件名
Size: Integer; //文件大小
sfile: TFileStream; //文件
end;
var
Form1: TForm1;
mem: fileinf;
posi, len: Integer;
implementation{$R *.DFM}procedure TForm1.Button3Click(Sender: TObject);
begin
if ClientSocket1.Active then
ClientSocket1.Active:=false;
application.Terminate;
end;procedure TForm1.Button2Click(Sender: TObject);
begin
if ClientSocket1.active then clientsocket1.Active:=false;
ClientSocket1.Host:= edit1.Text;
ClientSocket1.Port:= StrToInt(edit2.Text);
clientsocket1.active:=true;
// ClientSocket1.Active:=false;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if Opendialog1.Execute then
begin
edit3.Text:= Opendialog1.FileName;
mem.name:= getfilename(Opendialog1.FileName);
end;
end;procedure TForm1.ClientSocket1Connecting(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.lines.Add('C: 正在链接...');
end;procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
p: Array[0..1023] of byte;
RecStr: String;
begin
RecStr:= ClientSocket1.Socket.ReceiveText;
// Memo1.Lines.Add('S: '+RecStr);
if Pos('连接成功', RecStr)> 0 then
begin
Memo1.Lines.Add('连接成功');
Memo1.Lines.Add('C: 提交文件名');
ClientSocket1.Socket.SendText('提交文件名: '+mem.name);
end; if Pos('成功收到文件名', RecStr)> 0 then
begin
posi:=0;
len:=0;
Try
mem.sfile:= TFileStream.Create(mem.name, fmOpenRead);
mem.Size:= mem.sfile.Size;
Posi:= 0;
Memo1.Lines.Add('C: 提交文件大小');
ClientSocket1.Socket.SendText('提交文件大小: '+IntToStr(mem.size));
finally
// mem.sfile.Free;
end;
end;//end if if Pos('成功收到文件大小', RecStr)> 0 then
begin
Memo1.Lines.Add('C: 开始发送文件');
ClientSocket1.Socket.SendText('开始发送文件');
end; if (Pos('可以发送', RecStr)> 0) or (Pos('继续发送', RecStr)> 0) then
begin
try
//recfile:= TFileStream.Create(mem.name, fmOpenRead);
if Posi< mem.Size then
begin
len:= 1024;
if mem.Size-posi< 1024 then len:= mem.Size-posi;
mem.sfile.Position:=posi;
mem.sfile.ReadBuffer(p,len);
// mem.sfile.read(p,len);
ClientSocket1.Socket.SendBuf(p,len);
// memo1.lines.add('当前位置:'+inttostr(posi)+',长度:'+inttostr(len));
if ProgressBar2.Position<>Round(posi/mem.Size*100) then
Application.ProcessMessages;
ProgressBar2.Position:= Round(posi/mem.Size*100);
inc(posi, len);
end;
finally
//mem.sfile.Free;
//mem.sfile:=nil;
end;
end; if Pos('文件接收失败', RecStr)> 0 then
begin
Memo1.Lines.Add('C: 重新提交文件名');
ClientSocket1.Socket.SendText('提交文件名: '+mem.name);
end; if Pos('成功接收文件', RecStr)> 0 then
begin
mem.sfile.Free;
mem.sfile:=nil;
Memo1.Lines.Add('C: 发送文件结束');
ClientSocket1.Socket.SendText('发送文件结束');
end;
end;function TForm1.getfilename(str1:string):string;
var
myi:integer;
str2:string;
begin
str2:='';
if length(str1)=0 then result:=''
else
begin
if pos('\',str1)<1 then result:=str1
else
begin
for myi:=length(str1) downto 1 do
begin
if str1[myi]='\' then Break;
str2:=str1[myi]+str2;
end;
result:=str2;
end;
end;
end;end.
//服务端
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ComCtrls, StdCtrls, ScktComp;type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
ProgressBar1: TProgressBar;
Button3: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
Sendf: boolean;
filename:String;
filesize:integer;
recfile: TFileStream;
ReadCount : integer;
implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
begin
if Button1.Caption = 'Active' then
begin
Button1.Caption := 'Stop';
ServerSocket1.Active := true;
end
else begin
Button1.Caption := 'Active';
ServerSocket1.Active := false;
end;
sendf:=false;
end;procedure TForm1.Button2Click(Sender: TObject);
begin if ServerSocket1.Active then
ServerSocket1.Active:= False;
application.Terminate;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
button1Click(self);end;procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
socket.SendText('连接成功...');end;procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
recStr: String;
Buffer : pointer;
nRetr : integer;
const
bufferSize = 1024 ;begin
if not sendf then
begin
RecStr:= socket.ReceiveText;
memo1.Lines.add(recstr);
end;
if Pos('提交文件名', RecStr)>0 then
begin
delete(RecStr, 1, length('提交文件名: '));
filename:='.\data\'+RecStr;
socket.SendText('成功收到文件名');
end; if Pos('提交文件大小', RecStr)>0 then
begin
delete(RecStr, 1, length('提交文件大小: '));
fileSize:=StrToIntDef(RecStr,0);
if FileExists(Filename) then Deletefile(filename);
recfile :=TFileStream.Create(filename,fmCreate or fmShareDenyNone);
{ if recfile<>nil then
begin
recfile.Free;
recfile:= nil;
end;}
socket.SendText('成功收到文件大小');
end; if sendf then
begin
GetMem(Buffer,BufferSize);
nRetr := Socket.ReceiveBuf(Buffer^,BufferSize);
inc(readcount, nretr);
ProgressBar1.Position:= Round(readcount/filesize*100);
Application.ProcessMessages; {if FIleExists(filename) then
begin
recfile :=TFileStream.Create(filename,fmOpenWrite or fmShareDenyNone);
recfile.Seek(0,soFromEnd);
end;}
recfile.write(Buffer^,nRetr);
FreeMem(Buffer);
//recfile.Free;
//recfile:= nil; if readcount=filesize then
begin
memo1.Lines.add('成功接收文件');
socket.SendText('成功接收文件');
recfile.Free;
recfile:=nil;
sendf:=false;
end
else socket.SendText('继续发送');
end; if Pos('开始发送文件', RecStr)>0 then
begin
socket.SendText('可以发送');
ReadCount:=0;
sendf:=true;
end;
end;procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
showmessage('客户已停止链接');
end;procedure TForm1.ServerSocket1ClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
showmessage('客户已出错');
end;end.