stream的接收问题(50分)

  • 主题发起人 主题发起人 hly
  • 开始时间 开始时间
H

hly

Unregistered / Unconfirmed
GUEST, unregistred user!
TMemoryStream* pms = new TMemoryStream();
pms->LoadFromFile("e:/Project1.exe");
ClientSocket1->Socket->SendStream(pms);

ServerSocket1->Socket->?????
用什么来接收客户端发来的stream
如果这个stream很大,我怎样把他分段发送和分段接收呢?
 
这个问题不是很难吧!
 
发端:用seek()定位,读取指定字节数,发走.
收段:用seek()定位,写指定字节数.
 
如果这个stream很大,我怎样把他分段发送和分段接收呢?
====>

如果流很大, Tserversocket 会给你自动分发,你放心用sendstream,
不过在发送前你要通知client ,将要发送的流的SIZE,以便CLIENT处理。

在client 端就应该在recve到数据后,检查收到的流的
SIZE,如果这个SIZE 和先前SERVER通知我的那个SIZE相等,
就表示server 送来的流全部收到.

处理逻辑就是这样:


 
大虾,我还是不太懂,能结合源程序讲解吗?
 
服务器端用那个函数来接收?
说啊,你的处理逻辑!!!
 
以下是部分delphi 代码:

以下Server 端处理.:

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
RecvTxt :string;
begin
RecvTxt := Socket .ReceiveText;
if RecvTxt = 'Get Screen' then
begin
GetScreen (Image );
ImageStream .Clear ;
Image .SaveToStream (ImageStream );
ImageStream .Position := 0;
Socket .SendText ('SIZE:'+IntToStr (ImageStream .Size ));
end
else
if RecvTxt = 'Ok' then
begin
ImageStream .Position := 0;
Socket .SendStream (ImageStream );
end
else
begin
Memo1 .Lines .Add ('Time : '+ FormatDateTime ('hh:nn:ss',now()) + 'Recv: ' + RecvTxt + ' From: ' + Socket .LocalAddress );
end;
end;

以下Client 端处理.:

procedure TForm2.ClientSocket1Read(Sender: TObject;
Socket: TCustomWinSocket);
Var
RecvText :String ;
Buf :array[0..10000] of Byte ;
RecvLen:Integer ;
Bmp :TBitmap;
begin
if ImageSize = 0 then //Imagesize 为单员级变量.
begin
RecvText := Socket .ReceiveText();
if copy(RecvText ,1,4) = 'SIZE' then
begin
ImageSize := StrToInt (Copy(RecvText ,6,Length(RecvText)-5 ));
ClientSocket1 .Socket .SendText ('Ok');
end;
end
else
begin
RecvLen := Socket .ReceiveLength ;
StatusBar1 .SimpleText := '正在接收数据,数据长度为'+ IntToStr (RecvLen )+ 'Byte.';
Socket .ReceiveBuf (Buf ,RecvLen );
if MemoryStream .Size < ImageSize then
begin
MemoryStream.Write(Buf ,RecvLen );
end;
if MemoryStream .Size >= ImageSize then
begin
MemoryStream .Position := 0;
Jpg .LoadFromStream (MemoryStream );
try
Jpg .SaveToFile ('c:/windows/desktop/1.jpg');
finally
ImageSize := 0;
end;

end;
end;
end;



 
我的程序现在能用了,但还是有个小问题:
要传送的文件project1.exe有4000k;

TMemoryStream * pms =new TMemoryStream();

pms->LoadFromFile("e:/project1.exe");
pms->Position=0;
Socket->SendStream(pms);
却只能传送8k就不传了,怎样才能让他传送完呢?
 
把你的CODE 贴出来,我帮你看看.
 

void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
TMemoryStream * pms1=new TMemoryStream();

byte buff[800000];
len=Socket->ReceiveLength();

Socket->ReceiveBuf(buff,len);

// if(pms1->Size>=leng)
// pms1->SaveToFile("e:/honglueyi.exe");
Edit2->Text=IntToStr(len);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
TMemoryStream * pms =new TMemoryStream();
pms->LoadFromFile("e:/project1.exe");
leng=pms->Size;
Socket->SendStream(pms);
Edit1->Text=IntToStr(leng);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
ClientSocket1->Socket->SendText("ok");
}
//------------------------------------------

有劳大虾了!
谢谢
 
修改了一下,:


....
TMemoryStream * pms1=new TMemoryStream();
int size ; //记录收到DATA的SIZE。
......
void __fastcall TForm1::ClientSocket1Read(TObject *Sender,
TCustomWinSocket *Socket)
{
// TMemoryStream * pms1=new TMemoryStream(); <==用一个全局变量.
byte buff[800000];
if size = 0 //SERVER还没有开始...
{
size = StrToInt(Socket.recvtext) ;
Socket.Senttext("I have Knowed size");
}
else
{
if(pms1->Size < leng) //还没有全部收到.
{
len=Socket->ReceiveLength();
Socket->ReceiveBuf(buff,len);
pms1->Write(buff,len);
};
if(pms1->Size >= leng)
{
pms1->SaveToFile("e:/honglueyi.exe");
Edit2->Text=IntToStr(len);
};
}
}

//---------------------------------------------------------------------------

....
TMemoryStream * pms =new TMemoryStream();
......

void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
//TMemoryStream * pms =new TMemoryStream(); 也用全局变量吧.
char *text ;
text = Socket->RecvText("ok");
if text = 'ok'
{
pms->LoadFromFile("e:/project1.exe");
leng=pms->Size;
Socket->Sendtext(IntToStr(leng));
Edit1->Text=IntToStr(leng);
}
else
{
if text = 'I have Knowed size'
{
Socket->SendStream(pms);
}
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
ClientSocket1->Socket->SendText("ok");
}
//------------------------------------------

我没有装C++ builder ,没有调试,但思路应该没错!

 
To Jhdandcl
首先感谢你的答复,我的程序作了些改进,但总还是不行
程序中e:/setup.bmp size is 71618 byte
而程序只能传64266 byte
换了别的文件也一样,总有一些byte传不完。
我的程序如下,能帮我好好看看吗?
万分感谢!

//----------
private: // User declarations
TMemoryStream * cpms;
TMemoryStream * spms;
long int receivesize;
public: // User declarations
void __fastcall TForm1::FormCreate(TObject *Sender)
{
cpms=new TMemoryStream();
spms=new TMemoryStream();
receivesize=0;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::BitBtn1Click(TObject *Sender)
{
c->Socket->SendText("ok");
}
//---------------------------------------------------------------------------
void __fastcall TForm1::sClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
String text;
text=Socket->ReceiveText();
if(text=="ok")
{
ShowMessage("s--ok");
spms->LoadFromFile("e:/setup.bmp");
spms->Size;
Socket->SendText(IntToStr(spms->Size));
}
if(text=="already")
{
ShowMessage("s--sendstream(spms)");
spms->Position=0;
Socket->SendStream(spms);

}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::cRead(TObject *Sender, TCustomWinSocket *Socket)
{

byte buffer[10000];
if(receivesize==0)
{
receivesize=StrToInt(Socket->ReceiveText());
c->Socket->SendText("already");
ShowMessage(IntToStr(receivesize));
}
else
{
Socket->ReceiveBuf(buffer,Socket->ReceiveLength());
cpms->Write(buffer,Socket->ReceiveLength());
ShowMessage("cpms length is "+IntToStr(cpms->Size));

if(cpms->Size>=receivesize)
{
cpms->Position=0;
cpms->SaveToFile("e:/hhh.bmp");
delete cpms;
}
}
}
//---------------------------------------------------------------------------
 
多人接受答案了。
 
后退
顶部