100分 socket问题:在局域网内用clientsocket和serversocket进行文件传送,但为何接收到的文件内容为空??(100分)

  • 主题发起人 主题发起人 djrj
  • 开始时间 开始时间
D

djrj

Unregistered / Unconfirmed
GUEST, unregistred user!
在局域网内用clientsocket和serversocket进行文件传送,客户端用clientsocket,服务器端用
serversocket,要求文件是从客户端传送到服务器端,代码如下,但传送完毕后我发现文件
字节数为零!!!100分,很急啊!!!

- - - 客户端clientsocket - - -

procedure TForm1.Button2Click(Sender: TObject); //点击BUTTON2后开始传送文件。
var
fmess:TStringList;
begin
fmess:=TStringList.Create; //创建一个字符串列表,用来传送文件名和文件大小
stream:= TMemoryStream.Create; //创建一个内存流
if OpenDialog1.Execute then //打开文件
begin
stream.LoadFromFile(OpenDialog1.FileName);//将文件读入内存流
count:= 0; //已传送文件字节数,初始置为零
fmess.Values['tag']:='000';
fmess.Values['fname']:=ExtractFileName(OpenDiaLog1.FileName); //获取文件名
fmess.Values['fsize']:=IntToStr(stream.Size);//获取文件大小
ClientSocket1.Socket.SendText(fmess.Text); //先发送文件名和文件大小
end;
end;

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

- - - 服务器端serversocket - - -
procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf: array [1..2048] of char; //定义绶冲区
rcvtxt: string;
fmess:TStringList;
left,len: integer;
begin
fmess:=TStringList.Create;
fmess.Text:=Socket.ReceiveText;
if fmess.Values['tag']='000' then //若接收的是文件信息
begin
fname:= fmess.Values['fname']; //获得文件名
size:= StrToInt(fmess.Values['fsize']); //获得文件大小
count:= 0; //置已接收的文件字节数为零
SaveDialog1.InitialDir:=dir;
SaveDialog1.FileName:=fname;
if SaveDialog1.Execute then
begin
AssignFile(ToF, SaveDialog1.FileName);
Rewrite(ToF, 1);
end;
Socket.SendText('go');
end
else //接收文件内容
begin
left := size - count;
if left>sizeof(buf) then //若满一块则接收一块
begin
Socket.ReceiveBuf(buf,sizeof(buf));
BlockWrite(Tof,buf,sizeof(buf));
count := count + sizeof(buf);
Socket.SendText('go');
end
else //若未满一块则接收余下的字节
begin
Socket.ReceiveBuf(buf,left);
BlockWrite(Tof,buf,left);
CloseFile(Tof);
end;
end;
end;
 
呵呵,我已经搞懂了!
只好白白送分了。呜……呜……呜……
泼出去的水,收不回来。
我决定将100分平均分配给看这个问题的前两个人,
看谁走运了……
好心痛!!!!
 
我来了,问题出在哪里了??
 
问题自己解决了,那么帮忙解决我的问题:
有没有尝试过用sendbuf和receivebuf来实现文件传送?
 
我啊,没用阻塞,一样没问题的,发200M的没有问题
 
楼上兄弟能发个源代码给我吗!
dyxfkj@163.com
 
你的stream读完文件后,忘记把Position属性置为0了。
 
你不信
TFileStream.size始终为0
 
现在又发现问:
发完一个文件后,若还要再发另一个文件,则server端就会出现 I/O Error 103
只有重新启动程序后才能发,
也就是说当一个文件传送接收完毕后如何让它能传送第二个文件。
 
省得麻烦啦,给你些源码(可不是我自己写的),在接收第二个文件时,程序并没有新开
文件,而是附加在第一个文件里。
unit Unit1;

interface

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

type
TCon = record
FileName : String;
TotalSize : Integer;
Status : Integer;
end;

PCON = ^TCON;

TForm1 = class(TForm)
GroupBox1: TGroupBox;
GroupBox2: TGroupBox;
ClientSocket: TClientSocket;
ServerSocket: TServerSocket;
btnServerActive: TButton;
btnClientCon: TButton;
btnClientDisConn: TButton;
BtnClientSendF: TButton;
Memo1: TMemo;
OpenDialog: TOpenDialog;
Edit1: TEdit;
Label1: TLabel;
procedure btnClientConClick(Sender: TObject);
procedure btnClientDisConnClick(Sender: TObject);
procedure BtnClientSendFClick(Sender: TObject);
procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure btnServerActiveClick(Sender: TObject);
procedure ServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
procedure ServerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

var Count : Integer;

function GetFileSize(const FileName: string):integer;
var f : TFileStream;
begin
f := TFileStream.Create(FileName,fmOpenRead or fmShareDenyNone);
Result :=f.Size;
F.Free;
end;

procedure TForm1.btnClientConClick(Sender: TObject);
begin
ClientSocket.Active := True;
with OpenDialog do
begin
Execute;
if FileName <> '' then
begin
Edit1.Text := 'UPLOAD '+ ExtractFileName(FileName) +' '+Inttostr(GetFileSize(FileName));
Label1.Caption := FileName;
ClientSocket.Socket.SendText(edit1.Text);
end;
end;
end;

procedure TForm1.btnClientDisConnClick(Sender: TObject);
begin
ClientSocket.Active := False;
end;

procedure TForm1.BtnClientSendFClick(Sender: TObject);
var fs : TFileStream;
Buf : pointer;
begin
fs := TFileStream.Create(Label1.Caption ,fmOpenRead or fmShareDenyNone);
GetMem(Buf,fs.Size);
fs.Seek(0,soFromBeginning);
fs.ReadBuffer(Buf^,fs.Size);
memo1.Lines.Add('has send : '+inttostr(ClientSocket.Socket.SendBuf(Buf^,fs.Size)));
end;

procedure TForm1.ClientSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1.Lines.add(socket.ReceiveText);
end;

procedure TForm1.ClientSocketError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode := 0;
end;

procedure TForm1.btnServerActiveClick(Sender: TObject);
begin
ServerSocket.Active := True;
end;

procedure TForm1.ServerSocketClientConnect(Sender: TObject;
Socket: TCustomWinSocket);
var c : pcon;
begin
c :=new(pcon);
c.FileName := '';
c.TotalSize := 0 ;
c.Status := 0;
Socket.Data := c;
Socket.SendText('已经连接,请输入UPLOAD FILENAME SIZE'#13#10);
end;

procedure TForm1.ServerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var C : PCON;
cmd:String;
Buffer : pointer;
nRetr : integer;
fs : TFileStream;
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;
Socket.SendText('you can send File !'#13#10);
end;
end;
1 :
begin
Count := count + 1;
GetMem(Buffer,BufferSize);
nRetr := Socket.ReceiveBuf(Buffer^,BufferSize);
Memo1.Lines.Add(IntToStr(Count) + ' ' + IntToStr(nRetr));
if not FIleExists('c:/'+c.FileName) then
begin
fs :=TFileStream.Create('c:/'+c.FileName,fmCreate or fmShareDenyNone);
fs.Seek(0,soFromBeginning);
end
else
begin
fs :=TFileStream.Create('c:/'+c.FileName,fmOpenWrite or fmShareDenyNone);
fs.Seek(0,soFromEnd);
end;
fs.WriteBuffer(Buffer^,nRetr);
fs.Destroy;
FreeMem(Buffer);
end;
end;
end;

procedure TForm1.ServerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
ErrorCode := 0;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Count := 0;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ClientSocket.Active := False;
ServerSocket.Active := False;
end;

end.
 
接受答案了.
 
后退
顶部