300分的问题!!——关于缓冲问题。(300分)

  • 主题发起人 主题发起人 Writer
  • 开始时间 开始时间
W

Writer

Unregistered / Unconfirmed
GUEST, unregistred user!
问题一(100分)、
我用TFileStream编文件分割器,在定义缓冲时出现错误。
请看下面的代码:
var
Buffer:array [1..1048576] of PChar;
在调试时就出现错误??而:
var
Buffer:array [1..544288] of PChar;
就可以通过。
是不是缓冲有上限的??(有相关资料者可另加50分)


问题二(200分)。
关于TServerSocket和TClientSocket之间传输文件时的怪现像。

//TClientSocket端,收文件的一端
unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
CS: TClientSocket;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure CSRead(Sender: TObject
Socket: TCustomWinSocket);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
CX:Integer;
FS:TFileStream;
implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
begin
CS.Active:=True;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
CS.Socket.SendText('DL');
CX:=1888256;
FS:=TFileStream.Create('E:/Oicq.exe',fmCreate);
end;

procedure TForm1.CSRead(Sender: TObject
Socket: TCustomWinSocket);
var
Buf:array [1..2048] of Char;
begin
if CX>2048 then
begin
Socket.ReceiveBuf(Buf,SizeOf(Buf));
FS.Write(Buf,SizeOf(Buf));
CX:=CX-SizeOf(Buf);
Socket.SendText('DL');
end
else
begin
Socket.ReceiveBuf(Buf,CX);
FS.Write(Buf,CX);
Fs.Free;
end;

end;

end.







//TServerSocket端,为发送方
unit Unit1;

interface

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

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

var
Form1: TForm1;
FS:TFileStream;
CX:integer;
implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
FS:=TfileStream.Create('E:/qq/oicq.exe',fmOpenread);
cx:=1888256;
end;

procedure TForm1.SSClientRead(Sender: TObject
Socket: TCustomWinSocket);
var
Buf:array [1..2048] of char;

begin
if socket.ReceiveText='DL' then
begin
if cx<=sizeof(buf) then
begin
fs.Read(buf,cx);
socket.SendBuf(buf,cx);
end
else
begin
fs.Read(buf,sizeof(buf));
socket.SendBuf(buf,sizeof(buf));
Cx:=cx-sizeof(buf);
end;
end;
end;

end.




现象:当第一次发送文件成功,但第二次发送完成后,发过来的文件虽然和TClientSocket端的原文件大小一样,但就不能运行,图标变为了DOS的可执行文件的图标。请指出错处。










 
问题一:
我觉得不是你提到的问题引起的错误。能不能把你的贴出来看看。
问题二:
暂时没有想法。
 
你在发送端在发送完文件后,要free一下吧
if socket.ReceiveText='DL' then
begin
if cx<=sizeof(buf) then
begin
fs.Read(buf,cx);
socket.SendBuf(buf,cx);
就是这句// fs.free;
end
 
问题二解决啦,200分快来。

procedure TForm1.SSClientRead(Sender: TObject
Socket: TCustomWinSocket);
var
Buf:array [1..2048] of char;

begin
if socket.ReceiveText='DL' then
begin
if cx<=sizeof(buf) then
begin
fs.Read(buf,cx);
socket.SendBuf(buf,cx)

cx:=1888256;
end
else
begin
fs.Read(buf,sizeof(buf));
socket.SendBuf(buf,sizeof(buf));
Cx:=cx-sizeof(buf);
end;
end;
end;

 
问题一,因为你定义的是静态数组,静态数组好像是有大小限制的.
建议使用动态数组.在分割文件时,例如每个文件600K,那么可以采用多个段复制文件,
读一段写一段.
每段比较小(例如10K),速度还是蛮快的,根本没有必要把整个文件读入内存.
 
你定义局部数组太大了,超过了为程序分配的栈空间。
在 Project Options 选项中 Linker 页 Memory sizes 一组中可以设置
Min stack size(最小栈空间)、Max stack size(最大栈空间),
而 Max stack size 的默认值是 $00100000 即 1048576,单位我想是 Byte?
而 PChar 是指针,占 4 个 Byte。你可以增加这个默认的 Max(Min) stack size 的值,
但建议还是动态在堆中分配内存较好。
 
多人接受答案了。
 
后退
顶部