高手请进!SendBuf与ReceiveBuf问题。(谢绝灌水!!!)

寒星 2001-09-12 01:04:32
小弟在使用ClientSocket与ServerSocket进行文件传输时出现错误。代码如下:
Type
TMyData = record
strFile: String;
bData: array [1..1000000] of byte;
end;

procedure TForm1.ClientSocketWrite(Sender: TObject; Socket: TCustomWinSocket);
var
MyData: TMyData;
begin
MyData.strFile := 'aaa.txt';
ClientSocket.socket.sendbuf(MyData.bData,sizeof(MyData.bData));
end;

procedure TForm1.ServerSocketRead(Sender: TObject; Socket: TCustomWinSocket);
var
MyData: TMyData;
iLen: Integer;
begin
iLen := socket.ReceiveLength;
socket.ReceiveBuf(MyData,iLen);
end;
请各位高手帮忙,谢谢啦!
...全文
369 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
寒星 2001-09-14
  • 打赏
  • 举报
回复
给分了。
newyj 2001-09-13
  • 打赏
  • 举报
回复

太长了 ;ms.Write(packet.data,packet.size); ); //执行到这行时报栈溢出
不知你ms:=tmemorystream.create 执行了没有
要不吧你的东东发到newyj@263.net
寒星 2001-09-13
  • 打赏
  • 举报
回复
to newyj(方恨少):
我按你给出的例子试写了一段代码,但发生错误,代码如下,请帮忙看看:
Client端:
procedure TEClient.ToolButton1Click(Sender: TObject);
var
strFile: String;
ms:TMemoryStream;
packet:TFilePack;
isendlen,i,Position,len:integer;
begin
if not myclient.Active then
showmessage('Please connect server.')
else
begin
if opendialog1.Execute then
begin
strFile := OpenDialog1.FileName;
{ sendstr := 'Send File' + strFile + '//';
sendlen := length(sendstr);
for I:=1 to sendlen do
buffer[I] := byte(sendstr[I]);
}
// SendFile := TFileStream.Create(strFile,fmOpenRead);
// len := SendFile.Read(buffer,100000);
// myclient.Socket.SendBuf(buffer,len);
// SendData(strFile);
ms:=TmemoryStream.Create;
ms.LoadFromFile(strFile);
len:=ms.Size-ms.Position;
while len>0 do
begin
fillchar(Packet,Sizeof(TFilepack),0);
if len>2043 then
begin
packet.size:= 2044;
packet.flag:='d';
end
else
begin
packet.size:=len;
packet.flag:='e';
end;
ms.Read(packet.data,packet.size);
isendlen:=Myclient.Socket.SendBuf(packet,sizeof(TFilePack));
len:=ms.Size-ms.Position;
end;
end;
end;
end;
Server端:
procedure TEServer.MyServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf:array [0..1024000] of byte;
packet:Tfilepack;
PacketLen ,i,ReceiveLen:integer;
begin

PacketLen := SizeOf(TFilepack);
ReceiveLen := Socket.ReceiveLength;
if (ReceiveLen mod PacketLen) <> 0 then
begin
showmessage('error');
Exit;
end;
Socket.ReceiveBuf(Buf, ReceiveLen);
for i := 0 to ReceiveLen div SizeOf(TFilepack) - 1 do
begind
Move(Buf, packet, PacketLen);
case packet.flag of
'd': ms.Write(packet.data,packet.size); //执行到这行时报栈溢出
'e': begin
ms.Write(packet,packet.size);
ms.SaveToFile('d:\aaa.dat');
// ms.SetSize(0);
end;
else
;
end;
end;

//socket.SendBuf(sendtxt,sizeof(TsendTxt));
Move(Buf[PacketLen], Buf, ReceiveLen - (i + 1) * PacketLen);
end;
寒星 2001-09-13
  • 打赏
  • 举报
回复
to newyj(方恨少):
我按你给出的例子试写了一段代码,但发生错误,代码如下,请帮忙看看:
Client端:
procedure TEClient.ToolButton1Click(Sender: TObject);
var
strFile: String;
ms:TMemoryStream;
packet:TFilePack;
isendlen,i,Position,len:integer;
begin
if not myclient.Active then
showmessage('Please connect server.')
else
begin
if opendialog1.Execute then
begin
strFile := OpenDialog1.FileName;
{ sendstr := 'Send File' + strFile + '//';
sendlen := length(sendstr);
for I:=1 to sendlen do
buffer[I] := byte(sendstr[I]);
}
// SendFile := TFileStream.Create(strFile,fmOpenRead);
// len := SendFile.Read(buffer,100000);
// myclient.Socket.SendBuf(buffer,len);
// SendData(strFile);
ms:=TmemoryStream.Create;
ms.LoadFromFile(strFile);
len:=ms.Size-ms.Position;
while len>0 do
begin
fillchar(Packet,Sizeof(TFilepack),0);
if len>2043 then
begin
packet.size:= 2044;
packet.flag:='d';
end
else
begin
packet.size:=len;
packet.flag:='e';
end;
ms.Read(packet.data,packet.size);
isendlen:=Myclient.Socket.SendBuf(packet,sizeof(TFilePack));
len:=ms.Size-ms.Position;
end;
end;
end;
end;
Server端:
procedure TEServer.MyServerClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
buf:array [0..1024000] of byte;
packet:Tfilepack;
PacketLen ,i,ReceiveLen:integer;
begin

PacketLen := SizeOf(TFilepack);
ReceiveLen := Socket.ReceiveLength;
if (ReceiveLen mod PacketLen) <> 0 then
begin
showmessage('error');
Exit;
end;
Socket.ReceiveBuf(Buf, ReceiveLen);
for i := 0 to ReceiveLen div SizeOf(TFilepack) - 1 do
begin
Move(Buf, packet, PacketLen);
case packet.flag of
'd': ms.Write(packet.data,packet.size); //执行到这行时报栈溢出
'e': begin
ms.Write(packet,packet.size);
ms.SaveToFile('d:\aaa.dat');
// ms.SetSize(0);
end;
else
;
end;
end;

//socket.SendBuf(sendtxt,sizeof(TsendTxt));
Move(Buf[PacketLen], Buf, ReceiveLen - (i + 1) * PacketLen);
end;
寒星 2001-09-13
  • 打赏
  • 举报
回复
抱歉,我忘了执行ms:=tmemorystream.create。但是这段代码好象无法传超过4K的文件。这样吧,我把代码发给你,帮忙看看,谢谢啦。
blackfiles 2001-09-12
  • 打赏
  • 举报
回复
Delphi的NMStrm使用于远程传送么?它最大可以传送多大的东西??
newyj 2001-09-12
  • 打赏
  • 举报
回复
flag标志包的类型;
'd'就是文件
'e'文件传送结束
newyj 2001-09-12
  • 打赏
  • 举报
回复
unit Unit1;

interface

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

type
TFilePack=packed record
flag:char;
data:array [0..2042] of byte;
size:integer;
end;
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
Memo1: TMemo;
SpeedButton3: TSpeedButton;
ADODataSet1: TADODataSet;
procedure FormCreate(Sender: TObject);
procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
procedure SpeedButton3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
var
ms:Tmemorystream;

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
ClientSocket1.Active:=true;
ms:=Tmemorystream.Create;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
var
buf:array [0..1024000] of byte;
packet:Tfilepack;
PacketLen ,i,ReceiveLen:integer;
begin

PacketLen := SizeOf(TFilepack);
ReceiveLen := Socket.ReceiveLength;
memo1.Lines.Add(inttostr(ReceiveLen));
if (ReceiveLen mod PacketLen) <> 0 then
Exit;
Socket.ReceiveBuf(Buf, ReceiveLen);
for i := 0 to ReceiveLen div SizeOf(TFilepack) - 1 do
begin
Move(Buf, packet, PacketLen);
// memo1.Lines.Add('rec '+inttostr(Socket.SocketHandle));
case packet.flag of
'd': ms.Write(packet.data,packet.size);
'e': begin
ms.Write(packet,packet.size);
ms.SaveToFile('e:\11.exe');
// ms.SetSize(0);
end;
else
;
end;


//socket.SendBuf(sendtxt,sizeof(TsendTxt));
Move(Buf[PacketLen], Buf, ReceiveLen - (i + 1) * PacketLen);
end;

end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
ms.SaveToFile('e:\122.exe');
adodataset1.State
end;

end.
寒星 2001-09-12
  • 打赏
  • 举报
回复
to newyj(方恨少):
你给的例子中的flag在接收时起什么作用?能给出接收的例子吗?成分感谢!
yymmme 2001-09-12
  • 打赏
  • 举报
回复
好好查一查,包长是有限制的,不是你想多少就多少。比如UDP的包长是2k
newyj 2001-09-12
  • 打赏
  • 举报
回复
我发送文件的实例
unit Unit1;

interface

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

type
TFilePack=packed record
flag:char;
data:array [0..2042] of byte;
size:integer;
end;
TForm1 = class(TForm)
ServerSocket1: TServerSocket;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
Memo1: TMemo;
procedure senddata;
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.senddata;
var
ms:TMemoryStream;
packet:TFilePack;
isendlen,i,Position,len:integer;

begin
ms:=TmemoryStream.Create;
ms.LoadFromFile('D:\Project1.exe');
len:=ms.Size-ms.Position;
while len>0 do
begin
fillchar(Packet,Sizeof(TFilepack),0);

if len>2043 then
begin
packet.size:= 2044;
packet.flag:='d';
end
else begin
packet.size:=len;
packet.flag:='e';
end;

ms.Read(packet.data,packet.size);
for i:=0 to ServerSocket1.Socket.ActiveConnections-1 do
isendlen:=serversocket1.Socket.Connections[i].SendBuf(packet,sizeof(TFilePack));
memo1.Lines.Add(inttostr(isendlen));
len:=ms.Size-ms.Position;
end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
senddata;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
serversocket1.Active:=true;
end;

end.
newyj 2001-09-12
  • 打赏
  • 举报
回复
1.
sizeof(MyData.bData)=1000004
strFile: String; string;是指针 sizeof (strFile)=4;
2:包太大了
ClientSocket一次最多读8k

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧