IceE+Qt实现简易的文件传输

Zeroc-Ice是一个大而全面的跨平台中间件技术框架,但是很多项目场景仅仅需要其中间件通信能力即可,下面我们采用Zeroc-Ice其裁剪过的IceE实现简单的文件传输实现,IceE在嵌入式领域使用更多,另外QT在嵌入式可视化界面开发也受欢迎,两者结合一起实现一个简要的 demo,展示IceE如何实现通信。

1)下载IceE,依据其编译帮助文件说明编译所在平台所需语言的依赖库,本文采用IceE-1.3.0的早期版本:(IceE-1.3.0.zip-嵌入式代码类资源-CSDN下载

,其文件结构如下图,能在当前绝大多数嵌入式系统适用。当然,如果已经部署或编译好了Zeroc-Ice,直接采用Zeroc-Ice一样能实现本文测试样例,即使是最新的3.7版本Zeroc-Ice一样可行,仅需要其通信能力。

2)编译出 IceE的头文件和静态库,本文采用vs2010和g++4.4.7编译器编译,下来构建通信接口文件RCI.ice,该接口文件定义了文件描述信息和文件传输相关接口函数,具体如下:

#ifndef _IEVENT_ICE
#define _IEVENT_ICE

#include <IceE/Identity.ice>

module RCI
{
/********自定义数据结构*********//
	struct RCIFileBinary
	{
		string filename;
		int    startpos;
		int    filesize;
		string filebuf;
		int    buflen;
	};

	sequence<string> RCISeqList;
*******接口*******/	
	interface RCIAccess
	{	
//***元素是数据处理方法***//	
		/*
		getFileByConf:
		描述:
			请求开始读取原始数据文件数据。
		参数:
			file:		文件名;;
			replyid:	服务端返回的应答编号;
		返回值:
			true: 表示成功;
			false:表示失败.
		*/
		bool getFileByConf(string file,out int replyid);	

		/*
		nextFileData:
		描述:
			获取原始数据信息。
		参数:
			replyid:	服务端返回的应答编号;
			filedata:	用于缓存返回的数据;
		返回值:
			true:	表示成功;
			false: 表示失败。
		*/
		bool nextFileData(int replyid,out RCIFileBinary filedata);

		/*
		getRawDataDir:
		描述:
			获取原始数据文件目录信息。
		参数:
			dirlist:	用于存储所有满足条件的文件名容器;
		返回值:
			true: 表示成功获取到文件列表;
			false:表示失败.
		*/
		bool getRawDataDir(out RCISeqList dirlist);
	};	
};

#endif

3)根据RCI.ice生成需要编译语言的实际接口源码文件,本文要和Qt结合,因此会采用slice2cppe.exe来编译c++源码,因此进入 RCI.ice所在目录,执行命令如下:

D:/work/ICE_test/IceE-1.3.0/cpp/bin/slice2cppe.exe -ID:/work/ICE_test/IceE-1.3.0/slice RCI.ice

最好是把该命令写入到脚本中,如ICE.bat,这样方便使用,当然也可以添加其他命令,如将生成源码拷贝到指定目录等

执行命令生成RCI.h/RCI.cpp源码文件

4)安装好QT,建议如果要在生产环境的嵌入式系统使用,采用类似于4.7,4.8的版本,防止有些嵌入式系统不支持更高级的QT版本,类似c++11/14/17,也慎重选择,本文测试时安装在win7下的QT4.8版本,并采用vs2010编译成了静态库,linux下测试是redehat6.5版本,qt4.8同样静态编译,g++是4.4版本的。

OK,看看本文测试工程的目录结构如下

client        #客户端
IceE          #IceE头文件
IceE-1.3.0    #IceE源码包
IceRc         #ice通信接口文件、脚本及生成代码
Lib           #编译好的win/linux的IceE库
server        #服务端

5)先构建服务端的pro工程文件,ICEServer.h/ICEServer.cpp是基于RCI.h/RCI.cpp编写的真正实现通信接口的源文件,如下:

QT      +=  core

CONFIG += qt warn_on debug_and_release
CONFIG += console
CONFIG += static

DESTDIR = bin
ProDir=..

INCLUDEPATH              += $$ProDir
INCLUDEPATH              += $$ProDir/IceRc 
INCLUDEPATH              += $$ProDir/server/IceSrc

win32{
    DEFINES +=  QTWIN_32 \
                ICE_API_EXPORTS \
                ICEE_STATIC_LIBS \
                WIN32_LEAN_AND_MEAN \
                QT_CORE_LIB \
                QT_GUI_LIB \
                QT_NETWORK_LIB \
                QT_HAVE_MMX \ 
                QT_HAVE_3DNOW \
                QT_HAVE_SSE \
                QT_HAVE_MMXEXT \
                QT_HAVE_SSE2 \
                QT_THREAD_SUPPORT \
                QT_LARGEFILE_SUPPORT \
                WIN32 \
                _UNICODE \

    DEFINES -= VSWIN_32 \
}

unix{
    DEFINES +=  ICE_API_EXPORTS \
            ICEE_STATIC_LIBS \
            QT_CORE_LIB \
}

CONFIG(debug, debug|release) {
    TARGET = ICEServer_debug
    CONFIG += console
    OBJECTS_DIR             = debug/obj
    MOC_DIR                 = debug/moc
    DEFINES                 += _DEBUG
} else {
    TARGET = ICEServer_release
    OBJECTS_DIR             = release/obj
    MOC_DIR                 = release/moc
    DEFINES                 += NODEBUG
}

win32:LIBS += Rpcrt4.lib
win32:CONFIG(debug, debug|release) {
    win32:LIBS             += $$ProDir/Lib/debug/icee_staticd100.lib
} else {
    win32:LIBS             += $$ProDir/Lib/release/icee_static100.lib
}
unix{
    LIBS       += -L"$$ProDir/Lib/linux" -lIceE_4.4
}
#代码
HEADERS +=  $$ProDir/IceRc/RCI.h 
HEADERS +=  IceSrc/ICEServer.h 
SOURCES +=  $$ProDir/IceRc/RCI.cpp 
SOURCES +=  IceSrc/ICEServer.cpp 

SOURCES +=  main.cpp 

服务端实现代码接口及涉及的源码如下

bin            #执行文件输出目录
IceSrc         #ICEServer.h、ICEServer.cpp接口文件存储目录
ICEServer.pro  #工程文件
main.cpp       #

main.cpp


#include <IceE/IceE.h>
#include "IceSrc/ICEServer.h"

using namespace std;

int run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
{
    if(argc > 1)
    {
        fprintf(stderr, "%s: too many arguments\n", argv[0]);
        return EXIT_FAILURE;
    }
    fprintf(stderr, "%s: create Adapte now! \n", argv[0]);
    Ice::ObjectAdapterPtr adapter = communicator->createObjectAdapter("RCI");
    ::RCI::RCIAccessPtr object = new RCIAccessI;
    adapter->add(object, communicator->stringToIdentity("RCI"));
    adapter->activate();
    fprintf(stderr, "%s: Adapte be activated now! \n", argv[0]);
    communicator->waitForShutdown();
    return EXIT_SUCCESS;
}

int main(int argc, char* argv[])
{
    int status;
    Ice::CommunicatorPtr communicator;

    try
    {
        Ice::InitializationData initData;
        initData.properties = Ice::createProperties();
        initData.properties->load("config");
        communicator = Ice::initialize(argc, argv, initData);
        status = run(argc, argv, communicator);
    }
    catch(const Ice::Exception& ex)
    {
        fprintf(stderr, "%s\n", ex.toString().c_str());
        status = EXIT_FAILURE;
    }catch (const std::string & msg) {
        fprintf(stderr, "%s\n", msg.c_str());
        status = EXIT_FAILURE; 
    } catch (const char * msg) { 
        fprintf(stderr, "%s\n", msg);
        status = EXIT_FAILURE; 
    } 

    if(communicator)
    {
        try
        {
            communicator->destroy();
        }
        catch(const Ice::Exception& ex)
        {
            fprintf(stderr, "%s\n", ex.toString().c_str());
            status = EXIT_FAILURE;
        }
    }

    return status;
}

ICEServer.h

#ifndef ICECLIENT_H
#define ICECLIENT_H

#include "RCI.h"

#include <queue>
#include <IceE/IceE.h> 
#include <IceE/Thread.h>
#include <IceE/Mutex.h>

struct HanderArg
{
	::std::string  path;
};

class FileDataReadThread : public IceUtil::Thread
{
public:
	FileDataReadThread(HanderArg args);
	~FileDataReadThread();

	virtual void run();

	int getgloop();
	time_t getlasttime();
	bool emptybuffer();
	bool getfirstdata(::RCI::RCIFileBinary & filedataitem);
private:
	int gloop;
	time_t 	lasttime;
	HanderArg arglist;
	std::queue< ::RCI::RCIFileBinary > filedatals;
	IceUtil::Mutex mutexrdls;
};

typedef IceUtil::Handle<FileDataReadThread > FileDataReadThreadPtr;

class FDReadManageThread : public IceUtil::Thread
{
public:
	FDReadManageThread();
	~FDReadManageThread();

	virtual void run();

	bool createrequest(HanderArg args, int &replyid);
	bool getrequest(int reqid, ::RCI::RCIFileBinary& filedataitem);
private:
	std::list<FileDataReadThreadPtr> requestlist;
	IceUtil::Mutex listMutex;
};

typedef IceUtil::Handle<FDReadManageThread> FDReadManageThreadPtr;

// using namespace std;
class RCIAccessI : public RCI::RCIAccess { 
public:
	RCIAccessI();
	virtual ~RCIAccessI();
public:
	virtual bool getFileByConf(const ::std::string&
		, ::Ice::Int&
		, const ::Ice::Current& = ::Ice::Current());
	virtual bool nextFileData(::Ice::Int
		, ::RCI::RCIFileBinary&
		, const ::Ice::Current& = ::Ice::Current());
	virtual bool getRawDataDir(::RCI::RCISeqList&
		, const ::Ice::Current& = ::Ice::Current());
private:
	void init();
private:
	FDReadManageThreadPtr fdmgthptr;
};

#endif //ICECLIENT_H

ICEServer.cpp

#include "ICEServer.h"

#include <stdio.h>
#include <stdlib.h>

#ifdef __linux__ 
#include <sys/io.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif

#ifdef WIN32
#include <io.h>
#include <time.h>
#endif

#define CONTINUEINTERVAL 10000 //秒

#ifdef __linux__ 
	#define INT32 int
	#define UINT32 unsigned int
	#define O_BINARY 0
#endif

#define MAX_QUEUESIZE 100
/*
**将字符串按指定标识分段
*/
bool string_divide( std::vector<std::string> &_strlist,const std::string src,const std::string div)
{
	std::string _src = src;
	std::string::size_type _pos = _src.find(div);
	while(std::string::npos != _pos)
	{
		std::string _buf = "";
		_buf = _src.substr(0,_pos);
		_strlist.push_back(_buf);
		_src = _src.erase(0,_pos+div.size());
		_pos = _src.find(div.c_str());
	}
	if(!_src.empty()){
		_strlist.push_back(_src);
	}
	return true;
};

long fsize(FILE *stream)
{
    long curpos, length;
    curpos = ftell(stream);
    fseek(stream, 0L, SEEK_END);
    length = ftell(stream);
    fseek(stream, curpos, SEEK_SET);
    return length;
};

FileDataReadThread::FileDataReadThread(HanderArg args)
	: IceUtil::Thread()
{
	arglist = args;		
	gloop = 1;
	lasttime = time(NULL);
}

FileDataReadThread::~FileDataReadThread()
{

}

int FileDataReadThread::getgloop()
{
	return gloop;
}

time_t FileDataReadThread::getlasttime()
{
	return lasttime;
}
bool FileDataReadThread::emptybuffer()
{
	return filedatals.empty();
}
bool FileDataReadThread::getfirstdata(::RCI::RCIFileBinary & filedataitem)
{
	bool ret = false;
	while (1==gloop&&filedatals.empty())
	{
		IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); 
	}
	if (!filedatals.empty()){
	    mutexrdls.lock();
	    filedataitem = filedatals.front();
	    filedatals.pop();
	    mutexrdls.unlock();		
	    ret = true;
	}

	lasttime = time(NULL);

	return ret;
}

void FileDataReadThread::run()
{
	while(1==gloop)
	{
		::RCI::RCISeqList dirlist;
		dirlist.push_back(arglist.path);

		for (int i = 0; i < dirlist.size(); i++)
		{
			fprintf(stderr, "FILE: %s\n",dirlist[i].c_str());

			std::string filename = dirlist[i];
			std::vector<std::string> _strlist;
        	string_divide(_strlist,filename,"/");
        	if (_strlist.size()>1)
        	{
        		filename = _strlist[_strlist.size()-1];
        	}
		//
        	FILE *fd = NULL; //需要注意
			fd  = fopen(dirlist[i].c_str(),"rb");  
		    if(NULL==fd){   
		        printf("open %s failed!\n",dirlist[i].c_str());
		        break;
		    }
		    UINT32 filesize = fsize(fd);
		    fseek(fd,0,SEEK_SET);
		    printf("filesize: %d \n", filesize);
		    UINT32 pos = 0;
		    while(pos<filesize)
		    {
			    while(filedatals.size()>MAX_QUEUESIZE)
			    {
			    	IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(100)); 
			    }

		    	unsigned char data[1024] = {0};
			    memset(data,0,1024);
			    // printf("tell(fd) = %d \n",tell(fd) );
			    INT32 readlen = fread(data,sizeof(char),1024,fd);
			    if(!(readlen == 1024||(pos+readlen)==ftell(fd)))
			    { 
			        printf("read pcap data failed! return %d , wish:%d \n"
			        	, readlen, 1024);
			        break;
			    }
			    ::RCI::RCIFileBinary filedataitem;
			    filedataitem.filename = filename;
			    filedataitem.startpos = pos;
			    filedataitem.filesize = filesize;
			    filedataitem.buflen	= readlen;
			    filedataitem.filebuf = std::string((char*)data,readlen);
			    // printf("pos:%d buf: %d\n", filedataitem.startpos,filedataitem.buflen);
			    pos += readlen;
			    	
			    mutexrdls.lock();
			    filedatals.push(filedataitem);
			    mutexrdls.unlock();    	
		    }
		    fclose(fd);
		    printf("file: %s be dealwith finish!\n",dirlist[i].c_str() );
	    }	
	    gloop = 0;	
		IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); 
	}
}

/
FDReadManageThread::FDReadManageThread()
	: IceUtil::Thread()
{

}
FDReadManageThread::~FDReadManageThread()
{

}

void FDReadManageThread::run()
{
	while(1)
	{
		listMutex.lock();
		std::list<FileDataReadThreadPtr>::iterator it = requestlist.begin();
		while(it!=requestlist.end()){
			if (time(NULL)>((*it)->getlasttime()+CONTINUEINTERVAL)
				||(0==(*it)->getgloop()&&(*it)->emptybuffer()))
			{
				(*it)->getThreadControl().join();
				it = requestlist.erase(it);
			}else{
				it++;
			}
		}	
		listMutex.unlock();
		IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(100));
	}
}

bool FDReadManageThread::createrequest(HanderArg args, int &replyid)
{
	bool ret = true;
	replyid = -1;
	try{
		FileDataReadThreadPtr readthread = new FileDataReadThread(args); 
		readthread->start();
		replyid = readthread->getThreadControl().id();
		listMutex.lock();
		requestlist.push_back(readthread);
		listMutex.unlock();
		// printf("create reqid:%d \n", replyid);
	}catch(const Ice::Exception& ex){
        fprintf(stderr, "%s\n", ex.toString().c_str());
        ret = false;
    }

	return ret;
}

bool FDReadManageThread::getrequest(int reqid, ::RCI::RCIFileBinary& filedataitem)
{
	bool ret = false;
	// printf("reqid:%d\n", reqid );
	listMutex.lock();
	std::list<FileDataReadThreadPtr>::iterator it = requestlist.begin();
	while(it!=requestlist.end()){
		// printf("check reqid: %d \n", (*it)->getThreadControl().id());
		if (reqid == (*it)->getThreadControl().id())
		{
			ret = (*it)->getfirstdata(filedataitem);
			// printf("getrequest return :%d \n", ret);
			break;
		}
		it++;	
	}
	listMutex.unlock();
	return ret;
}


RCIAccessI::RCIAccessI()
	: RCI::RCIAccess()
{
	init();
}

RCIAccessI::~RCIAccessI()
{
	fdmgthptr->getThreadControl().join();
}

void RCIAccessI::init()
{
	fdmgthptr = new FDReadManageThread();
	fdmgthptr->start();
}

bool RCIAccessI::getFileByConf(const ::std::string& path
	, ::Ice::Int& replyid
	, const ::Ice::Current& )
{
	HanderArg args;
	args.path = path;

	return fdmgthptr->createrequest(args,replyid);
}
bool RCIAccessI::nextFileData(::Ice::Int replyid
	, ::RCI::RCIFileBinary& filedataitem
	, const ::Ice::Current& )
{
	return fdmgthptr->getrequest(replyid,filedataitem);
}

bool RCIAccessI::getRawDataDir(::RCI::RCISeqList& dirlist
	, const ::Ice::Current& )
{
	dirlist.push_back("data/1009843804.bin"); 
	dirlist.push_back("data/TNET003c30fe5c230c98bd.bin"); 
	return true;
}

6)构建客户端的pro工程文件,ICEClient.h/ICEClient.cpp是基于RCI.h/RCI.cpp编写的真正实现通信接口的源文件,如下:

QT      +=  core

CONFIG += qt warn_on debug_and_release
CONFIG += console
CONFIG += static

DESTDIR = bin
ProDir=..

INCLUDEPATH              += $$ProDir
INCLUDEPATH              += $$ProDir/IceRc 
INCLUDEPATH              += $$ProDir/clinet/IceSrc

win32{
    DEFINES +=  QTWIN_32 \
                ICE_API_EXPORTS \
                ICEE_STATIC_LIBS \
                WIN32_LEAN_AND_MEAN \
                QT_CORE_LIB \
                QT_GUI_LIB \
                QT_NETWORK_LIB \
                QT_HAVE_MMX \ 
                QT_HAVE_3DNOW \
                QT_HAVE_SSE \
                QT_HAVE_MMXEXT \
                QT_HAVE_SSE2 \
                QT_THREAD_SUPPORT \
                QT_LARGEFILE_SUPPORT \
                WIN32 \
                _UNICODE \

    DEFINES -= VSWIN_32 \
}

unix{
    DEFINES +=  ICE_API_EXPORTS \
            ICEE_STATIC_LIBS \
            QT_CORE_LIB \
}

CONFIG(debug, debug|release) {
    TARGET = ICEClient_debug
    CONFIG += console
    OBJECTS_DIR             = debug/obj
    MOC_DIR                 = debug/moc
    DEFINES                 += _DEBUG
} else {
    TARGET = ICEClient_release
    OBJECTS_DIR             = release/obj
    MOC_DIR                 = release/moc
    DEFINES                 += NODEBUG
}
win32:LIBS += Rpcrt4.lib
win32:CONFIG(debug, debug|release) {
    win32:LIBS             += $$ProDir/Lib/debug/icee_staticd100.lib
} else {
    win32:LIBS             += $$ProDir/Lib/release/icee_static100.lib
}
unix{
    LIBS       += -L"$$ProDir/Lib/linux" -lIceE_4.4
}
#源码
HEADERS +=  $$ProDir/IceRc/RCI.h 
HEADERS +=  IceSrc/ICEClient.h 

SOURCES +=  $$ProDir/IceRc/RCI.cpp 
SOURCES +=  IceSrc/ICEClient.cpp 

SOURCES +=  main.cpp 

客户端实现代码接口及涉及的源码如下:

bin            #执行文件输出目录
IceSrc         #ICEClient.h、ICEClient.cpp接口文件存储目录
ICEClient.pro  #工程文件
main.cpp       #

main.cpp源码:

#include <IceE/IceE.h>
#include "IceSrc/ICEClient.h"

extern bool EXITSTAT = true;

int main(int argc, char * argv[]) 
{ 
    EXITSTAT  = true;
    ICEClient *ptrICEClient = new ICEClient(argc,argv);
    ptrICEClient->start();
    while(EXITSTAT){
    	#ifdef WIN32
        ::Sleep(100);
        #else
        ::sleep(1);
        #endif
    }
    return 0;
}

ICEClient.h源码:

#ifndef ICECLIENT_H
#define ICECLIENT_H

#include <IceE/IceE.h> 
#include <IceE/thread.h>
#include <vector>

#include "RCI.h"

using namespace std;

class ICEClient : public IceUtil::Thread
{
public:
	ICEClient(int argc, char* argv[]);
	~ICEClient();

	virtual void run();
private:
	void init(int argc, char* argv[]);
	void destroy();

	void getDir();
	void getFile();
private:
	Ice::CommunicatorPtr communicator;
	::RCI::RCIAccessPrx twoway;

	std::vector<std::string> fileList;
};
#endif //ICECLIENT_H

ICEClient.cpp源码:

#include "ICEClient.h"

#include <stdio.h>
#include <fcntl.h>

#ifdef WIN32
#include <io.h>
#include <time.h>
#include <conio.h>
#endif

#ifdef __linux__
#include <sys/time.h>
#endif

extern bool EXITSTAT;

ICEClient::ICEClient(int argc, char* argv[])
{
    init(argc,argv);
}

ICEClient::~ICEClient()
{
    this->destroy();
}

void ICEClient::init(int argc, char* argv[])
{
    try
    {
        Ice::InitializationData initData;
        initData.properties = Ice::createProperties();
        initData.properties->load("config");
        communicator = Ice::initialize(argc, argv, initData);
        if(argc > 1)
        {
            fprintf(stderr, "%s: too many arguments\n", argv[0]);
            return ;
        }
        fprintf(stderr,"create client now! \n");
        Ice::PropertiesPtr properties = communicator->getProperties();
        const char* proxyProperty = "RCI.Proxy";
        string proxy = properties->getProperty(proxyProperty);
        if(proxy.empty())
        {
            fprintf(stderr, "%s: property `%s' not set\n", argv[0], proxyProperty);
            return ;
        }else{
            fprintf(stderr, "%s: property `%s' has be seted \n", argv[0], proxyProperty);
        }

        Ice::ObjectPrx base = communicator->stringToProxy(proxy);
        fprintf(stderr,"checkedCast now! \n");
        twoway = ::RCI::RCIAccessPrx::checkedCast(base->ice_twoway()->ice_timeout(-1));
        if(!twoway)
        {
            fprintf(stderr, "%s: invalid proxy\n", argv[0]);
            return ;
        }else{
            fprintf(stderr, "%s: right proxy\n", argv[0]);
        }
        ::RCI::RCIAccessPrx oneway = twoway->ice_oneway();
    #ifdef ICEE_HAS_BATCH
        ::RCI::RCIAccessPrx batchOneway = twoway->ice_batchOneway();
    #endif
        fprintf(stderr,"connet server! \n");        
    }
    catch(const Ice::Exception& ex)
    {
        fprintf(stderr, "%s\n", ex.toString().c_str());
    }
}

void ICEClient::destroy()
{
    if(communicator)
    {
        try
        {
            communicator->destroy();
        }
        catch(const Ice::Exception& ex)
        {
            fprintf(stderr, "%s\n", ex.toString().c_str());
        }
    }
}

void ICEClient::run()
{
    char c = EOF;
    while(c != 'x')
    {
        c = getchar();
        fprintf(stderr, "you import: %c \n", c);
        switch(c)
        {
            case 'a':
                getDir();
                break;
            case 'b':
                getFile();
                break;
            default:
                break;
        }
        IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(10)); 
    }
    EXITSTAT = false;
}

void ICEClient::getDir()
{
	try{
        ::RCI::RCISeqList dirlist;
    	twoway->getRawDataDir(dirlist); 
        fileList.clear();
    	for (int i = 0; i < dirlist.size(); i++)
		{
            fileList.push_back(dirlist[i]);
			fprintf(stderr, "FILE: %s \n",dirlist[i].c_str());
		}
    }catch(const Ice::Exception& ex){
        fprintf(stderr, "%s\n", ex.toString().c_str());
    }
}

void ICEClient::getFile()
{
	try{	
        if (fileList.empty())
        {
            return;
        }	
    	int replyid = -1;
        //本测试中只读取第一个文件传输测试
    	bool ret = twoway->getFileByConf(fileList[0],replyid); 
    	if (ret)
    	{
    		IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(100)); 
    		int rf = -1;
    		std::string file = "";
    		::RCI::RCIFileBinary filedata;
    		time_t tf= time(NULL);
    		while(twoway->nextFileData(replyid,filedata))
    		{
    			if (file!=filedata.filename||-1==rf)
    			{
    				file = filedata.filename;
    				if (-1!=rf)
    				{
    					close(rf);
    					rf = -1;
    					char buffer[256] = {0};
    					printf(buffer,"file: %s read finish\n",file.c_str());
    				}
                    #ifdef WIN32
    				rf = open(file.c_str(),O_CREAT|O_RDWR|O_BINARY);
                    #else
                    rf = open(file.c_str(),O_CREAT|O_RDWR,S_IRWXU);
                    #endif
    				if (rf<0)
    				{
    					// printf("create file failed\n" );
                        char errorbuf[256] = {0};
                        printf(errorbuf, "create file (%s) error with msg is: %s\n",file.c_str(),strerror(errno));
    					// fprintf(stderr, "create file (%s) error with msg is: %s\n",file.c_str(),strerror(errno));
    					break;
    				}else{
    					lseek(rf,0,SEEK_SET);
    					char buffer[256] = {0};
    					printf(buffer,"start read file: %s \n",file.c_str());
    				}
    			}
    			write(rf, filedata.filebuf.c_str(), filedata.buflen);
                // IceUtil::ThreadControl::sleep(IceUtil::Time::milliSeconds(1)); 
    		}
    		if (-1!=rf)
    		{
    			close(rf);
    		}
    		int ll = (int)(time(NULL) - tf);
            char buftime[256] = {0};
		    printf(buftime,"time lval = %d s\n", ll);
    	}					
	}catch(const Ice::Exception& ex){
        fprintf(stderr, "%s\n", ex.toString().c_str());
    }
}

7)编译qt工程,注意在win下,需要启动类似于Qt 4.8 64-bit for Desktop (MSVC 2010)命令窗口进入服务端和客户端运行:

qmake -o Makefile ICEClient.pro && make debug | make release(win use nmake)

qmake -o Makefile ICEServer.pro && make debug | make release(win use nmake)

8)配置IceE通信的配置文件,本文测试服务端和客户端都在一台电脑上,仅做简要配置:

服务端的config文件,放置在服务程序所在目录:

#
# The server creates one single object adapter with the name
# "RCI". The following line sets the endpoints for this
# adapter.
#
RCI.Endpoints=tcp -p 10005

#
# Warn about connection exceptions
#
Ice.Warn.Connections=1

#
# Network Tracing
#
# 0 = no network tracing
# 1 = trace connection establishment and closure
# 2 = like 1, but more detailed
# 3 = like 2, but also trace data transfer
#
#Ice.Trace.Network=1

#
# Protocol Tracing
#
# 0 = no protocol tracing
# 1 = trace protocol messages
#
#Ice.Trace.Protocol=1

客户端的config文件,放置在客户端程序所在目录:

#
# The client reads this property to create the reference to the
# "RCI" object in the server.
#
RCI.Proxy=RCI:tcp -p 10005

#
# Warn about connection exceptions
#
Ice.Warn.Connections=1

#
# Network Tracing
#
# 0 = no network tracing
# 1 = trace connection establishment and closure
# 2 = like 1, but more detailed
# 3 = like 2, but also trace data transfer
#
#Ice.Trace.Network=1

#
# Protocol Tracing
#
# 0 = no protocol tracing
# 1 = trace protocol messages
#
#Ice.Trace.Protocol=1

运行测试,在服务端执行文件下构建 data目录,放置一些测试文件,启动服务,然后在启动客户端,测试截图如下:

由此可见如果仅仅采用Zeroc-Ice的通信能力,采用IceE足够,并能快速实现跨平台、跨语言的通信交互,并 IceE也支持域名方式配置实现通信,搭建简要的云端服务也足够,喜欢的可以在此基础上进一步拓展。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

py_free-物联智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值