使用indy10下的idtcpclient传输文件问题

kese 2008-04-15 04:06:42
我用idtcpclient和idtcpserver传输文件时发生问题

客户端用的是
IdTCPClient1->IOHandler->Write(picfile,picfile->Size,true);//picfile是TFileStream*类型

服务器用的是
void __fastcall TServerForm::IdTCPServer1Execute(TIdContext *AContext)
{
TMemoryStream* buffer = new TMemoryStream();
AContext->Connection->IOHandler->ReadStream(buffer,picsize,true);//但是读取不到内容
.....
}
...全文
749 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
dikars 2010-05-04
  • 打赏
  • 举报
回复
还可以,就是INDY 10 AContext.Connection.IdIOHandler.WriteFile 怎么接收不清楚。
僵哥 2008-04-16
  • 打赏
  • 举报
回复
第三个参数设置为True就加了一个“协议头”,标示后续有多少内容。否则就不知道什么时候传完了。更不能进行叠加传送。
kese 2008-04-16
  • 打赏
  • 举报
回复
//方法一
// IdTCPClient1->IOHandler->WriteFile("1.jpg",true);


//方法二
// TFileStream* f = new TFileStream("1.jpg",Sysutils::fmOpenRead);
// this->IdTCPClient1->IOHandler->Write(f,f->Size,false);//关键是第三个参数设置为false
// delete f;

//方法三
TMemoryStream * buffer = new TMemoryStream();
buffer->LoadFromFile("1.jpg");
this->IdTCPClient1->IOHandler->Write(buffer,buffer->Size,false); //关键是第三个参数设置为false
delete buffer;

但是为什么第三个参数要这样设置呢?
kese 2008-04-16
  • 打赏
  • 举报
回复
例子做了一些改进,但是方法二失败了。

服务器端代码

__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
TFileStream* f = new TFileStream("1.jpg",Sysutils::fmOpenRead);
filesize = f->Size;
delete f;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::IdTCPServer1Execute(TIdContext *AContext)
{
TMemoryStream * buffer = new TMemoryStream();
AContext->Connection->IOHandler->ReadStream(buffer,filesize,false);
buffer->Position = 0;
TJPEGImage* jpg = new TJPEGImage();
jpg->LoadFromStream(buffer);
this->Image1->Picture->Graphic = jpg;
delete jpg;
delete buffer;
}
//---------------------------------------------------------------------------

void __fastcall TForm2::Button1Click(TObject *Sender)
{
this->Image1->Picture->Graphic = 0;
}


客户端代码

__fastcall TForm5::TForm5(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm5::Button1Click(TObject *Sender)
{
this->IdTCPClient1->Host = "en";
this->IdTCPClient1->Connect();
}
//---------------------------------------------------------------------------

void __fastcall TForm5::Button2Click(TObject *Sender)
{
//方法一成功了
IdTCPClient1->IOHandler->WriteFile("1.jpg",true);


//方法二失败了
// TFileStream* f = new TFileStream("1.jpg",Sysutils::fmOpenRead);
// this->IdTCPClient1->IOHandler->Write(f,f->Size,true);
// delete f;

}
路过路人乙 2008-04-16
  • 打赏
  • 举报
回复
MARK学习
ydlchina 2008-04-16
  • 打赏
  • 举报
回复
cpu占用大,可能与你传送的文件大小有关,放个IdAntiFreeze组件试试,或对于大文件还是分割传输比较好
kese 2008-04-16
  • 打赏
  • 举报
回复
僵哥,你可以看一下IdIOHandler.hpp中186行有这么一句
virtual void __fastcall Write(Classes::TStream* AStream, __int64 ASize = 0x000000000, bool AWriteByteCount = false)/* overload */;
似乎缺省就是设置false,而且我的程序中也发现设置true不能正确的发送文件,设置false就能正确的发送。

现在我的程序已经可以正确的工作了,但是不知道为什么服务器占用cpu很大,不知道如何将TIdContext *AContext调整。
kese 2008-04-15
  • 打赏
  • 举报
回复
程序似乎有进展了,感谢僵哥的提点,程序确实在不断的改进。
要吃饭了,明天再做。
僵哥 2008-04-15
  • 打赏
  • 举报
回复
void __fastcall TForm2::IdTCPServer1Execute(TIdContext *AContext)
{
// DeleteFile("ser.jpg");
TMemoryStream * buffer = new TMemoryStream();
AContext->Connection->IOHandler->ReadStream(buffer,{filesize 由于写入的时候带有一个长度,所以得先读取长度}-1,false);
buffer->Position = 0;
TFileStream* f = new TFileStream("ser.jpg",Classes::fmCreate);
f->CopyFrom(buffer,buffer->Size);
f->Free();
{delete f;//f->Free()已经销毁f,两句只能用其一。}
delete buffer;
}
kese 2008-04-15
  • 打赏
  • 举报
回复
我做了一个例子:
客户端
void __fastcall TForm5::Button1Click(TObject *Sender)
{
this->IdTCPClient1->Host = "en";
this->IdTCPClient1->Connect();
}
//---------------------------------------------------------------------------

void __fastcall TForm5::Button2Click(TObject *Sender)
{
IdTCPClient1->IOHandler->WriteFile("1.jpg",true);
}
//---------------------------------------------------------------------------

服务器端

__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
TFileStream* f = new TFileStream("1.jpg",Sysutils::fmOpenRead);
filesize = f->Size;
delete f;
}
//---------------------------------------------------------------------------
void __fastcall TForm2::IdTCPServer1Execute(TIdContext *AContext)
{
// DeleteFile("ser.jpg");
TMemoryStream * buffer = new TMemoryStream();
AContext->Connection->IOHandler->ReadStream(buffer,filesize,false);
// buffer->Position = 0;
// TFileStream* f = new TFileStream("ser.jpg",Classes::fmCreate);
// f->CopyFrom(buffer,buffer->Size);
// f->Free();
// delete f;
delete buffer;
}
//---------------------------------------------------------------------------

void __fastcall TForm2::IdTCPServer1Disconnect(TIdContext *AContext)
{
ShowMessage("disconnect");
}
当不屏蔽语句的时候,第一次可以保存文件,但是第二次就发现连接已经断开了。
ydlchina 2008-04-15
  • 打赏
  • 举报
回复
使用ReadString(int)分段接收,如果文件比较小,int参数就是文件大小
僵哥 2008-04-15
  • 打赏
  • 举报
回复
IdTCPClient1->IOHandler->Write(picfile,picfile->Size,true);//picfile是TFileStream*类型

这个请先确定picfile的position为0,建议使用
IdTCPClient1->IOHandler->Write(picfile,0,true);//picfile是TFileStream*类型

kese 2008-04-15
  • 打赏
  • 举报
回复
我用的是idtcpserver,并没有使用ftp,而且我的工程原来就做好了,关键是从indy9升级到indy10的时候发生了变化。现在发生了问题,还是希望用原来的代码,要改的话,最好也是少量的改动。
52vc 2008-04-15
  • 打赏
  • 举报
回复
用这个函数试试
void __fastcall TServerForm::idFTPServerStoreFile(
TIdFTPServerThread *ASender, const AnsiString AFileName,
bool AAppend, TStream *&VStream)

1,316

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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