4.发送命令
(1)主要用到的函数有
int send(int s,char *buf,int bufLen,int flags)
该函数将数据发送到已经建立的基于连接套接字,实际发送数据的最大长度受到TCP缓存大小的限制。
(2)数据发送格式
同数据接收格式。
(3)函数编制
void CmdSend()
{
lenAll = ((pBegin[2]*0x1000000)&0xFF000000)+
((pBegin[3]*0x10000)&0xFF0000)+((pBegin[4]*0x100)&0xFF00)+pBegin[5];
while(lenAll>0)
{
if(lenAll>4096)
realLen = send(commuSkt,pBegin+lenAll-lenAll,4096,0);
else
realLen = send(commuSkt,pBegin+lenAll-lenAll,lenAll,0);
lenAll = lenAll-realLen;
}
}
5.任务添加
(1)主要用到的函数
int taskSpawn(char *name,int priority,int options,int stackSize,FUNCPTR entryPt,int arg1,int arg2,int arg3,int arg4,int arg5,int arg6,int arg7,int arg8,int arg9,int arg10)
该函数用于发起entryPt指向的函数为入口的任务。
在多任务操作系统VxWorks下,任务由唯一的ID来,并且对应于某一个特定的任务名。系统支持256个优先级,0为最高级,255为最低优先级,对同级的所用任务采取抢占式调度。用户优先级设定为低于100。在程序中,同时发起命令循环接收任务,命令解释任务及命令发送任务,且接收和发送的优先级高于命令解释。
(2)程序编制
在mypro.c中添加主函数main()
Main()
{
init(0);
/*发起网络命令循环接收任务、命令解释任务、命令发送任务*/
taskSpawn(“netrecv”,114,0,2000,(FUNCPTR)recCmd,0,0,0,0,0,0,0,0,0,0);
taskSpawn(“explain”,116,0,2000,(FUNCPTR)CmdExplain,0,0,0,0,0,0,0,0,0,0);
taskSpawn(“netsend”,114,0,2000,(FUNCPTR)CmdSend,0,0,0,0,0,0,0,0,0,0);
}
三、PC机网络通讯
PC机使用CAsyncSocket类套接字编程,该类是CSocket类的基类。使用CAsyncSocket可以“同时”进行接收和发送,而不需要使用多线程,它能自动检测网络的通断,并在网络出错时自动调用OnClose()通知用户。
PC机作为客户端,只需通过IP地址连接到服务器即可。具体实现方法如下:
1.新建一个基于对话框的工程CSocketClient。
2.在对话框面板中加入,Edit(IDC_ Edit1~ IDC_ Edit10),按钮发送(IDC_SEND)、按钮退出(IDC_EXIT)。
3.新建一个类CMySocket,添加变量unsigned char sendBuff[4096]; char *buff;在该类中重载以下五个函数
(1)CMySocket::CMySocket()
{
}
(2)CMySocket::~CMySocket ()
{
}
(3)void CMySocket:: OnConnect (int nErrorCode)
{
BOOL nodelayflag = TRUE;
if(nErrorCode == 0)
{
SetSockOpt(TCP_NODELAY, &nodelayflag, sizeof (BOOL));
MessageBox(NULL,"网络连接成功!","系统初始化",MB_OK);
AsyncSelect(FD_WRITE|FD_CLOSE);
}
else
{
Close();
MessageBox(NULL,"无法连接","onConnect",MB_OK);
}
CAsyncSocket::OnConnect(nErrorCode);
}
(4)CMySocket:: OnReceive(int nErrorCode)
{
m_nLength=Receive(recvBuff,8,0);
len =((recvBuff[2]<<24)&0xFF000000)+((recvBuff[3]<<16)&0xFF0000)
+((recvBuff[4]<<8)<<0xFF00)+recvBuff[5];
m_nLength=Receive(recvBuff+8,len-8,0);
/*将接收到的数据分开并在Edit框中显示*/
……
}
(5)CMySocket::OnSend(int nErrorCode)
{
sendBuff[0] = charToNum(buff[2],buff[3]);
sendBuff[1] = charToNum(buff[4],buff[5]);
sendBuff[2] = ((8>>24)&0xFF);
sendBuff[3] = ((8>>16)&0xFF);
sendBuff[4] = ((8>>8)&0xFF);
sendBuff[5] = (8&0xFF);
sendBuff[6] =0;
sendBuff[7] =0;
Send(sendBuff,8,0);
}
(6)在该类中添加一个字符串转换成十六进制的函数。
char CMySocket::charToNum(char char1,char char2)
{
int tmpt1,tmpt2;
if(char1>='A'&&char1<='F')
tmpt1 = char1 - 'A'+0x0A;
else if(char1>='a'&&char1<='f')
tmpt1 = char1-'a'+0x0A;
else if(char1>='0'&&char1<='9')
tmpt1 = char1 - '0';
if(char2>='A'&&char2<='F')
tmpt2 = char2 - 'A'+0x0A;
else if(char2>='a'&&char2<='f')
tmpt2 = char2-'a'+0x0A;
else if(char2>='0'&&char2<='9')
tmpt2 = char2 - '0';
return( (tmpt1*16+tmpt2)&0xFF);
}
4.在CSocketClient类中添加成员变量
CMySocket cltSkt
5.在对话框窗体中加入初始化函数,并在该函数中添加创建套接字,与网络服务器连接的代码。
BOOL CSocketClient::OnInitDialog()
{
CDialog::OnInitDialog();
cltSkt.ShutDown(2);
cltSkt.m_hSocket=INVALID_SOCKET;
cltSkt.Create(0,SOCK_STREAM,FD_CONNECT);
cltSkt.Connect("192.168.0.88",2001);
}
6.在发送按钮中添加代码
Void CSocketClietn::OnButSend()
{
mtimer=500;
SetTimer(1,mtimer,NULL);
}
在工程中添加定时器事件。
void CSocketClient:: OnTimer(UINT nIDEvent)
{
cltSkt.buff="0x7300";
cltSkt.AsyncSelect(FD_WRITE|FD_CLOSE);
}
7.在退出按钮中添加代码
void CSocketClient::OnBtnExit()
{
KillTimer(1);
cltSkt.buff="0x7400";
cltSkt.AsyncSelect(FD_WRITE|FD_CLOSE);
cltSkt.Close();
this->EndDialog(5);
}
本文提供的通讯方式在某应用软件程序设计中已得到应用,系统稳定可靠,网络通讯功能正确,达到设计要求。
四、结语
基于实时传输的VxWorks系统为使用VxWorks开发高速数据采集系统提供了传输基础。VxWorks的网络功能健全,网络通讯易于实现,VxWorks的多任务性及丰富的进程通讯机制为实现复杂的功能提供了必要的手段。
参考文献
[1] 周启平,张杨,吴琼.开发指南与Tornado实用手册.中国电力出版社.
[2] 程敬原.VxWorks软件开发项目实例.中国电力出版社.
[3] 谭浩强.C程序设计.清华大学出版社.
[4] 清宏计算机工作室.Visual C++编程技巧(网络与数据库篇).机械工业出版社.
|