为什么接受的文件不能用?(100分)

B

bmwbey

Unregistered / Unconfirmed
GUEST, unregistred user!
我按照以前的一个帖子写SERVERSOCKET,CLIENTSOCKET传文件的例子,文件是传了,可是受到的
文件,TXT文件是乱码,EXE文件不是WIN32程序,这是怎么回事,那为大虾帮我看看我的代码!
CLIENT 代码

unit Unit1;

interface

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

type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
Button1: TButton;
cs: TClientSocket;
procedure Button1Click(Sender: TObject);
procedure csRead(Sender: TObject; Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
count:integer;
size:integer;
stream:TMemoryStream;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
filename:string;
fmess:TStringList;

begin
fmess:=tstringlist.Create;
stream:=tmemorystream.Create;
count:=0;
if opendialog1.Execute then
begin
filename:=opendialog1.FileName;
stream.LoadFromFile(filename);
fmess.Values['tag']:='000';
fmess.Values['fname']:=extractfilename(filename);
size:=stream.Size;
fmess.Values['fsize']:=inttostr(stream.Size);
cs.Socket.SendText(fmess.Text);
end;
end;


procedure TForm1.csRead(Sender: TObject;
Socket: TCustomWinSocket);

var
rcvtxt: string;
buf: array [1..2048] of byte;
left: integer;
begin
rcvtxt:= Socket.ReceiveText;
left:= size - count; //未读字节数
if AnsiPos('+ok',rcvtxt)=1 then //如果网络正常使用
begin
if sizeof(buf)<left then //若满一块则读一块
begin
stream.Read(buf,sizeof(buf));
Socket.SendBuf(buf,sizeof(buf));
count:= count + sizeof(buf);
stream.Position:=count;
end
else //不满则发剩余的
begin
stream.Read(buf,left);
Socket.SendBuf(buf,left);
end;
end;
end;

end.

SERVER 代码

unit Unit1;

interface

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




type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
count,size:integer;
tof:file;
implementation

{$R *.dfm}

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf: array [1..2048] of byte; //定义绶冲区
rcvtxt: string;
fmess:TStringList;
left,len: integer;

fname:string;

begin
fmess:=TStringList.Create;
fmess.Text:=Socket.ReceiveText;
if fmess.Values['tag']='000' then //若接收的是文件信息
begin
fname:= fmess.Values['fname']; //获得文件名
//showmessage(fname);
size:= StrToInt(fmess.Values['fsize']); //获得文件大小
//showmessage(inttostr(size));
count:= 0; //置已接收的文件字节数为零
AssignFile(ToF, 'c:/'+fname);
Rewrite(ToF, 1);
Socket.SendText('+ok');
end
else //接收文件内容
begin
left := size - count;
// showmessage('left'+inttostr(left));
if left>sizeof(buf) then //若满一块则接收一块
begin
Socket.ReceiveBuf(buf,sizeof(buf));
//showmessage('getfile');
BlockWrite(Tof,buf,sizeof(buf));
//showmessage('writefile');
count := count + sizeof(buf);
Socket.SendText('+ok');
end
else //若未满一块则接收余下的字节
begin
Socket.ReceiveBuf(buf,left);
BlockWrite(Tof,buf,left);
CloseFile(Tof);
end;
end;
end;


end.


 
粗略看了一下发现你这样接收是不行的,因为缓冲区的内容被你拿走,但接收可能还没完成
,你可以通过nReceived 判断接收是否完成
Stream: TfileStream;
while True do
begin
//从连接中读取数据到缓冲器中
nReceived := Socket.ReceiveBuf(Buffer,sizeof(Buffer));
if nReceived <= 0 then Break
else
Stream.Write(Buffer,nReceived);
// 延迟(200 milliseconds)
Time1 := GetTickCount;
while GetTickCount-Time1< 200 do;
end;
 
delphi浪客,我也发现了nReceived是为-1,我把代码改了,还是不行,能不能帮我再看一下!
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ScktComp, ExtCtrls;




type
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
procedure ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
count,size:integer;
fname:string;
implementation

{$R *.dfm}

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf: array [1..2048] of char; //定义绶冲区
fmess:TStringList;
left: integer;
nRetr : integer;
fs : TFileStream;
t:integer;
begin
fmess:=TStringList.Create;
fmess.Text:=Socket.ReceiveText;
if fmess.Values['tag']='000' then //若接收的是文件信息
begin
fname:= fmess.Values['fname']; //获得文件名
showmessage(fname);
size:= StrToInt(fmess.Values['fsize']); //获得文件大小
showmessage(inttostr(size));
count:= 0; //置已接收的文件字节数为零
Socket.SendText('+ok');
end
else //接收文件内容
begin
left := size - count;
if not FIleExists('c:/'+FName) then
begin
fs :=TFileStream.Create('c:/'+FName,fmCreate or fmShareDenyNone);
showmessage('create file success');
fs.Seek(0,soFromBeginning);
end
else
begin
fs :=TFileStream.Create('c:/'+FName,fmOpenWrite or fmShareDenyNone);
showmessage('success open file');
fs.Seek(0,soFromEnd);
end;
// showmessage('left'+inttostr(left));
if left>sizeof(buf) then //若满一块则接收一块
begin
while True do
begin
//从连接中读取数据到缓冲器中
nretr:=Socket.ReceiveBuf(buf,sizeof(buf));
if nretr<= 0 then Break
else
fs.WriteBuffer(Buf,nRetr);
// 延迟(200 milliseconds)
fs.Destroy;
//showmessage('writefile');
count := count + sizeof(buf);
Socket.SendText('+ok');
t:= GetTickCount;
while GetTickCount-T< 200 do;
end;

end
else //若未满一块则接收余下的字节
begin
while True do
begin
//从连接中读取数据到缓冲器中
nretr := Socket.ReceiveBuf(Buf,sizeof(Buf));
if nretr<= 0 then Break
else
fs.WriteBuffer(Buf,left);
// 延迟(200 milliseconds)
t:= GetTickCount;
while GetTickCount-T< 200 do;
end;
fs.Destroy;
end;
end;
end;


end.
 
我做过一个传送打文件的程序,去下吧!
http://wolfsoft.nugoo.com/srcdetail.asp?flag=2&amp;id=114
 
我的做法和你的不一样但保证可以收到文件(我亲自做试验验证的)
建议客户端改动
var
Form1: TForm1;
implementation
var
count:integer;
size:integer;
stream:TMemoryStream;
procedure TForm1.Button1Click(Sender: TObject);
var
filename:string;
fmess:TStringList;

begin
fmess:=tstringlist.Create;
stream:=tmemorystream.Create;
count:=0;
if opendialog1.Execute then
begin
filename:=opendialog1.FileName;
stream.LoadFromFile(filename);
fmess.Values['tag']:='000';
fmess.Values['fname']:=extractfilename(filename);
size:=stream.Size;
fmess.Values['fsize']:=inttostr(stream.Size);
cs.Socket.SendText(fmess.Text);
end;
end;

procedure TForm1.csRead(Sender: TObject;
Socket: TCustomWinSocket);
var
rcvtxt: string;
begin
rcvtxt:= Socket.ReceiveText;
if AnsiPos('+ok',rcvtxt)=1 then //如果网络正常使用
Socket.SendStream(stream);
end;
服务端该成如下
type TRevType = (rtText,rtOther);
var
Form1: TForm1;
count,size:integer;
fname:string;
RevType:TRevType;

implementation

procedure GetFile(var fs: TFileStream);
begin
if not FIleExists('c:/'+FName) then
begin
fs :=TFileStream.Create('c:/'+FName,fmCreate or fmShareDenyNone);
fs.Seek(0,soFromBeginning);
end
else
begin
fs :=TFileStream.Create('c:/'+FName,fmOpenWrite or fmShareDenyNone);
fs.Seek(0,soFromEnd);
end;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf: array [1..9999] of char; //定义绶冲区
fmess:TStringList;
nRetr : integer;
fs : TFileStream;
t: Cardinal;
begin
fmess:=TStringList.Create;
fmess.Text:=Socket.ReceiveText;
if fmess.Values['tag']='000' then //若接收的是文件信息
begin
fname:= fmess.Values['fname']; //获得文件名
size:= StrToInt(fmess.Values['fsize']); //获得文件大小
Socket.SendText('+ok');
RevType := rtText;
end;
case RevType of
rtText:
begin
GetFile(fs);
try
while True do
begin
nretr:=Socket.ReceiveBuf(buf,sizeof(buf));
if nretr<= 0 then Break
else
fs.WriteBuffer(Buf,nRetr);
t:= GetTickCount;
while GetTickCount-T< 200 do;
end;
finally
fs.Free;
RevType := rtOther;
end;
end;
rtOther :
begin
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
RevType := rtOther;
end;
 
代码太长,我想是你的代码发送时有问题
 
接受答案了.
 
delphi浪客谢谢你,能不能给个联系方法,已有我有问题能不能直接找你啊!
我的msn是bmwbey@hotmail.com.
 
顶部