网络变量

        大家好,我目前就职于一家工业制造公司,我的邮箱是wuxfei@gmail.com。在日常工作中,时常会有这样的需求:程序分为两部分,分别部署在两台机器上,在这里我们就称这两部分为A和B吧!

        一般情况下A与B需要相互传递整型、浮点、字符串等变量。传递整型变量可使得A与B协调工作,比如说A程序控制的设备就绪后,就需要告诉B程序,现在可以打印了,当B程序打印完毕后,也需要告知A程序,打印已经结束了。在这个简单的交互过程中,我们可以提取出两个交互变量:int nStartPrint; int nPrtFinished;,就是说在A程序和B程序间需要交互两个整型变量的值,以达到AB协作,共同完成打印(激光标刻)功能。


        在第一次看到这样的需求,首先想到是,使用CSocket,然后双方进行收发数据并解析,然后还原成相应的变量。显然,这是可行的,一方发送,另一方接受就可以了,无非就是在接收的时候用一些 if 语句来区分当前收到的是哪一个变量。但是,要是再想一下,若需要增加一些变量传输呢?那么程序是不是就需要做较大的改动呢?


        综上所述,就是为了将不同程序实体中的变量进行值的交换,交换同一个程序实体中变量是件很容易的事情,用等号就可以了,但交换不同程序实体中的变量就显得有点麻烦了。这里所说的变量,都是系统提供的基本变量,他们的作用域不能超出程序实体,但是要是我们若能设计出一种作用域能超出程序实体的自定义变量类型,那是不是,上面的问题就好解决了呢?我想应该是这样的。


        现在就开始设计网络变量吧!

        我们先看一下系统变量是如何传递变量值的,因为是在同一个程序实体中,显然,变量都是在同一内存上的,要交换值的话,直接执行一系列机器指令就能完成了。但网络变量不一样,因为它存在于不同机器上的程序实体中,这样就存在传输的问题。就是说需要交换的内容,是要经过某种通道来传输的。谈到了通道,很自然就能想到通道的两端,所以,首先我们必须实现的是通道两端的传输者,这里命名为CQNetVaribleClient和CQNetVaribleServer。这两个类的主要功能就是收、发网络变量的数据包。

 

        打个比方,CQNetVaribleClient和CQNetVaribleServer就相当于是两个公司的前台(下面简前台A和前台B),两个公司的员工就相当于是一些网络变量。当公司A的员工 a1 需要与公司B的员工 b1 发送信息(相当于程序中的赋值)时,a1就会写封信(相当于数据打包)然后将信交给前台A,前台A将信件发出;当前台B收到信件后,就会查看本公司的员工表(相当于是传输者的网络变量注册表),若找到了员工 b1 ,就会将把信件给到 b1 ,这样是不是就完成了a1 给 b1 赋值了呢?      

       

        通过上面的比方,CQNetVaribleClient和CQNetVaribleServe就需要为网络变量提供注册的功能。有了注册后,员工 a1 给员工 b1 传递信息的时候,就知道将信件给前台A就可以了;另一方面,前台 B 收到信件后,也就知道信件是给员工 b1 的了(她/他不会将信件扔掉,因为 b1 是存在于员工表中的)。以下是其实现接口,只用关心公有函数就可以了:

class AFX_EXT_CLASS CQNetVaribleClient  
{
public:
	CQNetVaribleClient();
	virtual ~CQNetVaribleClient();

public:
	// 注册变量;只有注册后,本地变量才能与远程变量同步;
	BOOL RegistVarible(CQNetVarible *pQNetVar);

	// 连接至远端,指明远端IP和PORT;只有连接成功了,才能完成同步;
	BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);

private:
	CNetVaribleClient *m_pNetVaribleClient;
};


class AFX_EXT_CLASS CQNetVaribleServer  
{
public:
	CQNetVaribleServer();
	virtual ~CQNetVaribleServer();

public:
	// 注册变量;只有注册后,本地变量才能与远程变量同步;
	BOOL RegistVarible(CQNetVarible *pQNetVar);

	// 创建Socket,一般指定端口号就行了;
	BOOL Create(UINT nSocketPort = 0, LPCTSTR lpszSocketAddress = NULL);

private:
	CNetVaribleServer *m_pNetVaribleServer;
};

 

        数据传输部分设计好后,先在就可以设计变量部分了,其应该具有普通变量一样好用的特性,其结构如下:

 

enum VARIBLE_EX_TYPE {	VARIBLE_EX_TYPE_INT=0, VARIBLE_EX_TYPE_DOUBLE, VARIBLE_EX_TYPE_CSTRING };

class CNetVarible;
class CNetVaribleClient;
class CNetVaribleServer;

class AFX_EXT_CLASS CQNetVarible  
{
public:
	CQNetVarible(CString strVaribleName, VARIBLE_EX_TYPE VaribleType, int iDefaultValue);
	CQNetVarible(CString strVaribleName, VARIBLE_EX_TYPE VaribleType, double dbDefaultValue);
	CQNetVarible(CString strVaribleName, VARIBLE_EX_TYPE VaribleType, CString strDefaultValue);
	virtual ~CQNetVarible();

public:
	// 转换为int变量,将对象赋值给int型变量
	operator int();
	
	// 转换为double变量,将对象赋值给double型变量
	operator double();
	
	// 转换为CString变量,将对象赋值给CString型变量
	operator CString();
	
	// 将int型变量赋值给对象
	operator = (int iValue);
	
	// 将double型变量赋值给对象
	operator = (double dbValue);
	
	// 将CString型变量赋值给对象
	operator = (CString strValue);
	
	// 将对象与int变量恒等比较
	bool operator == (int i);

private:
	CNetVarible *m_pNetVarible;

	friend class CQNetVaribleClient;
	friend class CQNetVaribleServer;
};

 

        说一下数据的传输过程:我们把普通变量赋值给网络变量时,网络变量就会通过自己的前台把“自身数据”发出去。另外前台收到数据后,先还原成一个临时网络变量,然后查找网络变量注册表,进而更新本地网络变量。

 下面再贴一下用法片段:

CQNetVarible NetVar_Name(_T("姓名"), VARIBLE_EX_TYPE_CSTRING, _T("吴祥飞"));
CQNetVarible NetVar_Age(_T("年龄"), VARIBLE_EX_TYPE_INT, 30);
CQNetVarible NetVar_Height(_T("身高"), VARIBLE_EX_TYPE_DOUBLE, 1.80);

CQNetVaribleClient NetVar_Client;
CQNetVaribleServer NetVar_Server;

void NetVarClientInitial(void)
{
	NetVar_Client.RegistVarible(&NetVar_Name);
	NetVar_Client.RegistVarible(&NetVar_Age);
	NetVar_Client.RegistVarible(&NetVar_Height);

	NetVar_Client.Connect(_T("127.0.0.1"), 7979);
}

void NetVarServerInitial(void)
{
	NetVar_Server.RegistVarible(&NetVar_Name);
	NetVar_Server.RegistVarible(&NetVar_Age);
	NetVar_Server.RegistVarible(&NetVar_Height);

	NetVar_Server.Create(7979, _T("127.0.0.1"));
}


 

网络变量的使用示例工程下载地址 http://code.google.com/p/use-netvar/downloads/detail?name=UseNetVar.7z&can=2&q=#makechanges,如有问题可给我发邮件wuxfei@gmail.com,工程中A是作为服务端 ,所以先启动A,同时可使用Dbview工具查看调试信息。

 

 

 

 
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值