网络上传输文件时,收到的文件与发送端的文件不相同,请问是怎么回事?(100分)

  • 主题发起人 主题发起人 Vinson
  • 开始时间 开始时间
V

Vinson

Unregistered / Unconfirmed
GUEST, unregistred user!
服务器端
unit Sever;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
Memo1: TMemo;
ProgressBar1: TProgressBar;
procedure FormCreate(Sender: TObject);
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;
toptions=(load,listen,api);
tinfo=(fname,size,path);



var
Form1: TForm1;

opt,loadopt:toptions;
info:tinfo;
m1:tmemorystream;

filesize:longint;//文件长度;
filename,filepath:string;
DestFile:File;
RecSize:Integer;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
m1:=tmemorystream.Create; //创建流对象
serversocket1.port:=7777;
serversocket1.Open;
opt:=listen;

end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var tem:string;
len:longint;//包长度
buffer:array [0..1023] of byte; //设置接收缓冲区
begin
case opt of //主循环
listen://监听状态 (1级)
begin
tem:=socket.ReceiveText;
Memo1.Lines.Add(tem);
if tem='SENDFILE' then begin
socket.SendText('getsize');
opt:=load;
loadopt:=listen;
info:=size;
end;//改变状态
end;

load ://接收流 (1级)
begin
case loadopt of
listen: //准备接收(2级)
begin
tem:=socket.ReceiveText;
Memo1.Lines.Add(tem);
case info of //准备接收的数据 (3级)
size: begin
info:=path;//改变状态
filesize:=strtoint(tem);
Progressbar1.Max:=filesize;
progressbar1.Position:=0;
socket.SendText('getpath');
end;
path: begin
info:=fname; //改变状态
filepath:=tem;
socket.SendText('getname');
end;
fname:begin
info:=size;
loadopt:=load;//改变状态
filename:=tem;
filename:='E:/Test/'+ExtractFilename(filename);
AssignFile(DestFile,filename);
ReWrite(DestFile,1);
socket.SendText('getdata');
end;
end;
end;
load: //接收中(2级)
begin

len:=socket.ReceiveLength; //读出包长度
socket.ReceiveBuf(buffer,len); //接收数据包并读入缓冲区内
BlockWrite(DestFile,buffer,len);
RecSize:=RecSize+len;
Progressbar1.Position:=RecSize;
Socket.SendText('getdata');
//m1.write(buffer,len); //追加入 流M 中
if RecSize>=filesize then//m1.Size>=filesize then //完成了流M 的传送
begin
//m1.Position:=0;
RecSize:=0;
Memo1.Lines.Add(filename);
//m1.SaveToFile(filename);
//copyfile(pchar(filename),pchar(filepath+filename),true);
CloseFile(DestFile);
opt:=listen; //开始重置状态
loadopt:=listen;
info:=size;
tem:='';
socket.SendText('loadfileok');
end;
end;
end; // of case loadopt
end; //接收流over

api ://执行各种命令 (1级)
begin
end;
end; //of case opt
end;


procedure TForm1.ServerSocket1Accept(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.Add('Ready for Receive...');
end;

end.
--------------------------------------------------------
客户端
unit Client;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ScktComp, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
Button1: TButton;
Button2: TButton;
OpenDialog1: TOpenDialog;
Edit1: TEdit;
Label1: TLabel;
Edit2: TEdit;
ProgressBar1: TProgressBar;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure Button2Click(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

m1:tmemorystream;
filesize:longint;
filepath,filename,shortname:string;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
m1:=tmemorystream.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
try
clientsocket1.Close;
clientsocket1.Port:=7777;
clientsocket1.Host:=Edit2.Text;
clientsocket1.Open;
except
caption:='not con';
end;

end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
Socket: TCustomWinSocket);
begin
caption:='ok';
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
caption:='连接失败';
errorcode:=0;

end;

procedure TForm1.Button2Click(Sender: TObject);
var
m:tmemorystream;
begin
if opendialog1.Execute then
begin
filename:=opendialog1.FileName;
shortname:=ExtractFileName(filename);
m:=tmemorystream.Create;//create 流对象 m
m.Position:=0;
m.LoadFromFile(filename);
filesize:=m.Size;
end;
clientsocket1.Socket.SendText('SENDFILE');

end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var m:tmemorystream;
tem:string;
buffer:Array[0..1023] of byte;
begin
tem:=clientsocket1.Socket.ReceiveText;
label1.Caption:=tem;

if tem='getsize' then
begin
clientsocket1.Socket.SendText(inttostr(filesize));
end;
if tem='getpath' then clientsocket1.Socket.SendText('d');
if tem='getname' then clientsocket1.Socket.SendText(filename);
progressbar1.Position:=0;

if tem='getdata' then
begin
m:=tmemorystream.Create;//create 流对象 m
m.Position:=0;
m.LoadFromFile(filename);
Progressbar1.Max:=m.Size;
if m.Position<m.Size then begin
m.Write(buffer,sizeof(buffer));
clientsocket1.Socket.Sendbuf(buffer,sizeof(buffer));
Progressbar1.Position:=m.Position;
end;

end;

end;

end.
 
不相同?指内容?大小?
加个CRC校验吧!
 
内容和大小都不相同,内容变成乱码,大小变长了
 
是数据流接收端出了问题!
 
能够具体点吗?
 
if tem='getdata' then
begin
m:=tmemorystream.Create;//create 流对象 m
m.Position:=0;
m.LoadFromFile(filename);
Progressbar1.Max:=m.Size;
if m.Position<m.Size then begin
m.Write(buffer,sizeof(buffer));
clientsocket1.Socket.Sendbuf(buffer,sizeof(buffer));
Progressbar1.Position:=m.Position;
end;
end;

似乎m.position没有变哦。在Write之前应该先Seek可以吧。

 
m.Write不是自动移动m.Position的吗?
 
想在网络中传送文件吧,我这儿有一个很好的例子,要的话,给个e_mail
 
vinson.ye@263.net
 
请问你是用的什么协议?是TCP还是UDP?
 
已经将文件发送到vinson.ye@263.net中
 
程序收到了,不过我要试一下!欢迎大家继续讨论。
 
OK,解决了!
 
接受答案了.
 
to 豆非
大哥,能给我发一个例子吗?我现在也急需用呀,多谢了。
 
to 豆非:能发一个文件传送的例子吗Email:thmin@nethyc.zjhz.net
 
后退
顶部