IdTCPServer传送word流stream read error问题(200分)

  • 主题发起人 主题发起人 风清云淡系明月
  • 开始时间 开始时间

风清云淡系明月

Unregistered / Unconfirmed
GUEST, unregistred user!
客户端:IdTCPClient1,OleContainer1,
服务器端:IdTCPServer1,OleContainer2,
需要在客户端和服务器端传送word文档,把客户端OleContainer1中加载的word文档用TMemoryStream传送到服务器端OleContainer2。
我的代码如下:
=================================客户端========================================
procedure TForm1.Btn_loadwordClick(Sender: TObject);
begin
OleContainer1 := TOleContainerAc.Create(Self);
OleContainer1.Parent := Panel1;
OleContainer1.AllowInPlace := True;
OleContainer1.Align :=alClient;
OleContainer1.Visible := True;
TOleContainerAc(OleContainer1).CannotDeactivate := True;
OleContainer1.CreateObjectFromFile('c:/temp.doc',false);
OleContainer1.DoVerb(-1);
end;

procedure TForm1.Btn_sendwordClick(Sender: TObject);
var
mstream : TMemoryStream;
sendsize : Longint;
begin
mstream := TMemoryStream.Create;
OleContainer1.UpdateObject;
OleContainer1.SaveToStream(mstream);
mstream.Position :=0;
sendsize := mstream.Size;
IdTCPClient.WriteLn('aa');
IdTCPClient.WriteInteger(sendsize);
IdTCPClient.WriteStream(mstream);
mstream.Free;
end;

================================服务器端=======================================

procedure TForm1.IdTCPServerExecute(AThread: TIdPeerThread);
var
msstream : TMemoryStream;
sendsize : Longint;
comm : string;
begin
msstream := TMemoryStream.Create;
with AThread.Connectiondo
begin
comm := ReadLn();
if (comm = 'aa') then
begin
sendsize := ReadInteger();
ReadStream(msstream,sendsize);
end;
end;
OleContainer2.LoadFromStream(msstream);
//出错啦!!!
OleContainer2.DoVerb(-1);
msstream.Free;

end;

运行时,服务器端报错:stream read error
更加奇怪的是,我在同一个程序中,这样写就可以!
procedure TForm1.Button10Click(Sender: TObject);
var
SendMsgStream : TMemoryStream;
begin

SendMsgStream:=TMemoryStream.create;
OleContainer1.UpdateObject;
OleContainer1.SaveToStream(SendMsgStream);
SendMsgStream.Position :=0;
OleContainer2.LoadFromStream(SendMsgStream);
OleContainer2.DoVerb(-1);
SendMsgStream.Free;
end;

在同一个程序中,SaveToStream和LoadFromStream没有任何问题,为什么通过IdTCPServer1传送后LoadFromStream出错??
请高手指点!!
 
你这段程序,我稍微改造了一下,然后测试,好像可以。
我没有找到你的OleContainer,就直接使用内存流读入文件,然后在接收完成后直接写入另外一个文件,成功的。
下面是你的代码,我只是做了这点修改,然后测试。
procedure TForm1.Button1Click(Sender:TObject);
begin
IdTCPServer1.Bindings.Items[0].IP:='127.0.0.1';
IdTCPServer1.Bindings.Items[0].Port:=7778;
IdTCPServer1.Active:=True;
IdTCPClient1.Host:='127.0.0.1';
IdTCPClient1.Port:=7778;
IdTCPClient1.Connect(-1);
end;

procedure TForm1.Button2Click(Sender:TObject);
var
mstream:TMemoryStream;
sendsize:Longint;
begin
mstream:=TMemoryStream.Create;
mstream.LoadFromFile('c:/1.doc');
mstream.Position:=0;
sendsize:=mstream.Size;
IdTCPClient1.WriteLn('aa');
IdTCPClient1.WriteInteger(sendsize);
IdTCPClient1.WriteStream(mstream);
mstream.Free;
end;

procedure TForm1.IdTCPServer1Execute(AThread:TIdPeerThread);
var
msstream:TMemoryStream;
sendsize:Longint;
comm:string;
begin
msstream:=TMemoryStream.Create;
with AThread.Connectiondo
begin
comm:=ReadLn();
if (comm='aa') then
begin
sendsize:=ReadInteger();
ReadStream(msstream,sendsize);
end;
end;
msstream.SaveToFile('c:/2.doc');
msstream.Free;
end;
 
保存到文件再打开,我测试过,是可以的,但是打开word速度太慢,直接从TMemoryStream中读取,该如何实现?
 
大家帮忙看看啊!
 
这样可以
================================服务器端=======================================

procedure TForm1.IdTCPServerExecute(AThread: TIdPeerThread);
var
msstream : TMemoryStream;
sendsize : Longint;
comm : string;
begin
msstream := TMemoryStream.Create;
with AThread.Connectiondo
begin
comm := ReadLn();
if (comm = 'aa') then
begin
sendsize := ReadInteger();
ReadStream(msstream,sendsize);
end;
end;
msstream.Position:=0;//一定加上
OleContainer2.LoadFromStream(msstream);
//出错啦!!!
OleContainer2.DoVerb(-1);
msstream.Free;

end;
 
刚才我测试了。加上就对,不加上就没有内容。你试试吧。
 
zywcd:
msstream.Position:=0;//一定加上
谢谢你的提醒,加上果然可以读到发来的文件了,但是读完后好像程序停住了,不响应。
编译时,报错,我又加了一句:
coinitialize(nil);
msstream.Position:=0 ;
OleContainer2.LoadFromStream(msstream);
OleContainer2.DoVerb(-1);
你的客户端word修改后,多发几次,程序还能运行么?
 
我刚才使用了RichEdit载入文件,然后修改了发送,很多次都可以很正常。
 
谢谢,RichEdit没问题,可是用word就不行了,一接收文件流就死机,都有点灰心了。
不知道大家有没有用IdTCPServer传送word流成功的?
 
那你当成二机制文件发送不可以吗?
 
传送任何文件都可以,更加不要说是Word啦。
 
怎样当作二进制文件来发送?
 
抱歉 ,我理解错了。你是需要先加载然后发送,然后对方接收再显示。
 
死机问题暂时对付了,又有新的问题了,IdTCPServer如何向 IdTCPClient1发送数据?
IdTCPClient1如何接受流?
 
服务器建立连接的时候,你需要定义变量记录下
AThread: TIdPeerThread吧,而且客户端不能断开连接,这样服务端想发数据的时候就使用
AThread实现,不管你写流还是其他都可以。
AThread.Connection.WriteLn(。。);
AThread.Connection.WriteStream(。。)
我看indy的demo,客户端读数据使用了线程读数据,或者使用定时器都缓冲区,如果有数据就回来,没有就不管。
网上有完整indy的demo.可以下载一个研究。
 
我照者例子写了一个,
服务器:
try
with IdTCPServer1.Threads.LockListdo
for I := 0 to Count - 1do
begin
AThread := Items;
//if AThread.Connection.Socket.Binding.PeerIP = 'hostname' then
if AThread.Connection.Socket.Binding.PeerIP = '127.0.0.1' then
//AThread.Connection.WriteLn('aa');
AThread.Connection.WriteInteger(sendsize);
AThread.Connection.WriteStream(mstream);
//AThread.Connection.CloseWriteBuffer ;
end;
finally
IdTCPServer1.Threads.UnlockList;
end;

客户端
procedure TReceiveThread.Execute;
begin
while not Terminateddo
begin
if Form1.IdTCPClient.Connected then
with Form1.IdTCPClientdo
begin
//FMsg := ReadLn();
//if (FMsg = 'aa') then
//begin
sendsize := ReadInteger();
ReadStream(ClientRecvStream,sendsize);
//end;

end;
end;

end;

注释去掉,加上都不行,好象不执行,客户端收不到消息
 
这个demo我运行过,使可行的。
 
谢谢大家的关注,已经解决,散分啦!
 
多人接受答案了。
 
后退
顶部