VxWorks编写服务器模板

35 篇文章 22 订阅
/**********************************************************************
 chengjy@felab, copyright 2002-2004
 vxSvr.h
 网络监控任务需要的常数,只定义相关常数,其它常数
 需要编程用户自己定义。
 **********************************************************************/
#ifndef _VXSVR_H
#define _VXSVR_H

/*服务器初始化情况*/
#define NET_INIT_LISTENSKT		0x01
#define NET_INIT_COMMUSKT		0x02
#define NET_INIT_NULL			0x00

/*定义网络关闭时是否要重新初始化*/
#define MODE_NET_DEFAULT			0	/*重新初始化*/
#define MODE_NET_REINIT			1	/*不再初始化*/

/*定义任务名*/
#define TNAME_NETINIT			"tNetInit"
#define TNAME_NETRECV			"tNetRecv"	
#define TNAME_NETSEND			"tNetSend"
#define TNAME_NETCHECKLINK	"tNetCheckLink"
#define TNAME_NETCLOSEALL		"tNetCloseAll"


/*用户任务堆栈大小*/
#define USER_STACK_SIZE			2000

/*taskSpawn使用的用户任务优先级*/
#define TPRI_NETCLOSEALL		101
#define TPRI_NETCHECKLINK		102
#define TPRI_NETRECV			103	
#define TPRI_NETSEND			104
#define TPRI_NETINIT			105
	
#endif	/*_VXSVR_H*/

/**********************************************************************
 chengjy@felab, copyright 2002-2004
 vxSvr.c
 VxWorks下建立服务器端的程序框架,加上了网络监测的模块。
 函数:	
			void netInit(int mode);
			void netCMDRecv();
			void netCMDSend();
			void netCloseAll(int mode);
			void netCheckLink();
 调用:			无
 被调用:		shell下手动调用
 说明:			编译下载完毕后,在shell下输入sp netInit 
 初始化服务器端即可。注意本文档仅仅是框架,用户还需要
 根据需要添加内容。为了简洁起见,函数都设定为无返回。
 **********************************************************************/
 
#include "vxWorks.h"
#include "taskLib.h"
#include "sockLib.h"
#include "inetLib.h"
#include "ioLib.h"
#include "logLib.h"
#include "string.h"
#include "stdio.h"
#include "netinet\\tcp.h"
#include "semLib.h"

#include "vxSvr.h"

int flagNetInit = NET_INIT_NULL;	/*服务器初始化标志,程序中省略了对应的判断和操作*/

int listenSkt;		/*侦听socket*/
int commuSkt;		/*通讯socket*/
SEM_ID semCmdLink;		/*网络连接出错信号灯*/

void netInit(int mode);
void netCMDRecv();
void netCMDSend();
void netCloseAll(int mode);
void netCheckLink();

/*此处需要extern 外部关于队列操作的函数和全局变量*/

/**********************************************************************
 void netInit(int mode);
 函数说明:	网络初始化程序
 参数:		mode,	分为MODE_NET_DEFAULT 和MODE_NET_REINIT	两种,
 					分别对应初始化侦听+通讯套接字和只
 					初始化通讯套接字两种。
 返回:		无
 调用:			
			void netCMDRecv();
			void netCMDSend();
			void netCheckLink();
 被调用:	用户程序初始化模块
			char netCloseAll(int mode);
 **********************************************************************/
void netInit(int mode)
{
	/*需要添加重入控制*/
	
	if(mode == MODE_NET_DEFAULT)
	{
		/*建立本地的侦听用套接字listenSkt 并bind和listen*/
	}

	/*接收外部联接,建立通讯套接字commuSkt*/

	if(1/*改成已经正确建立通讯套接字的判断*/)
	{	
		/*初始化网络通讯的缓冲对列*/

		/*初始化缓冲队列的信号灯*/
		
		/*发起网络命令循环接收任务、命令发送任务和网络监控任务*/
		taskDelete(taskNameToId(TNAME_NETCHECKLINK));
		taskSpawn(TNAME_NETCHECKLINK,TPRI_NETCHECKLINK,0,USER_STACK_SIZE,
					(FUNCPTR)netCheckLink,0,0,0,0,0,0,0,0,0,0);	
		taskDelete(taskNameToId(TNAME_NETRECV));
		taskSpawn(TNAME_NETRECV,TPRI_NETRECV,0,USER_STACK_SIZE,
					(FUNCPTR)netCMDRecv,0,0,0,0,0,0,0,0,0,0);		
		taskDelete(taskNameToId(TNAME_NETSEND));
		taskSpawn(TNAME_NETSEND,TPRI_NETSEND,0,USER_STACK_SIZE,
					(FUNCPTR)netCMDSend,0,0,0,0,0,0,0,0,0,0);
	}
}

/**********************************************************************
 void netCMDSend();
 函数说明: 循环从网络发送缓冲队列中取出数据并发送
 参数:		无
 返回:		无
 调用:		外部的队列处理函数
 被调用:	void netInit(int mode)
 **********************************************************************/
void netCMDSend()
{
	while(1)
	{
		/*从缓冲对列获取数据,此处使用信号灯同步,在
		  没有数据要发送时任务被阻塞,不会占用CPU*/

		/*发送数据*/
		if(send(commuSkt,0,0,0/*改成其它三个参数*/) == ERROR)
		{
			/*发送错误*/
			logMsg("netSend: error in sending buff to client\n",0,0,0,0,0,0);
			semGive(semCmdLink);
			break;
		}
	}
}

/**********************************************************************
 void netCMDRecv()
 函数说明:	从已经建立的网络通道循环接收数据,并添加到接收
 				缓冲队列等待处理
 参数:		无
 返回:		无
 调用:		外部的队列处理函数
 被调用: STATUS netInit();
 **********************************************************************/
void netCMDRecv()
{
	int	recvLen;		/*实际接收数据的长度*/
	while(1)
	{
		recvLen = recv(commuSkt,0,0,0/*改成其他三个参数*/);
		if(recvLen!=ERROR && recvLen!=0)
		{
			/*添加到队列中等待处理*/
		}
		else
		{
			/*接收出错*/
			logMsg("netCMDRecv: error in receive data from client\n",0,0,0,0,0,0);
			semGive(semCmdLink);
			break;
		}
	}
}

	
/**********************************************************************
 void netCloseAll(int mode)
 函数说明:   	函数说明:  关闭侦听socket ,并删除命令缓冲
 				队列以及与socket相关的任务,并根据模式的
 				不同选择是直接关闭侦听套接字 (MODE_NET_DEFAULT) 
 				还是重新初始化网络(MODE_NET_REINIT)
 参数:		mode,	选择关闭方式
 返回:		无
 调用:		void netInit(int mode);
 被调用: void netCheckLink();
 			用户在shell下调用
 **********************************************************************/
void netCloseAll(int mode)
{
	int taskId;

	/*删除网络相关任务*/
	taskId = taskNameToId(TNAME_NETRECV);
	if(taskId!=taskIdSelf() && taskId!=ERROR)
	{
		taskDelete(taskId);
	}
	taskId = taskNameToId(TNAME_NETSEND);
	if(taskId!=taskIdSelf() && taskId!=ERROR)
	{
		taskDelete(taskId);
	}
	taskId = taskNameToId(TNAME_NETCHECKLINK);
	if(taskId!=taskIdSelf() && taskId!=ERROR)
	{
		taskDelete(taskId);
	}

	/*调用外部函数删除缓冲队列*/
	/*删除缓冲队列的信号灯*/

	/*删除网络通断检测用信号灯*/
	semDelete(semCmdLink);
	
	/*根据网络初始化的不同状态作相应的退出工作*/
	if(mode==MODE_NET_DEFAULT)
	{
		close(commuSkt);
		close(listenSkt);
	}
	else if(mode==MODE_NET_REINIT)
	{
		close(listenSkt);
		/*重新初始化网络*/
		taskDelete(taskNameToId(TNAME_NETINIT));
		taskSpawn(TNAME_NETINIT,TPRI_NETINIT,0,USER_STACK_SIZE,
					(FUNCPTR)netInit,mode,0,0,0,0,0,0,0,0,0);	
	}
}


/**********************************************************************
 void netCheckLink()
 函数说明:	监测网络状态,出错即关闭网络并重新初始化
 参数:		无
 返回:		无
 调用:
 			char netCloseAll(int mode)
 被调用:
 			void netInit();
 **********************************************************************/
void netCheckLink()
{
	/*由于优先极高,因此先创建信号灯才会进行网络的接收和发送*/
	semCmdLink = semBCreate(SEM_Q_FIFO,SEM_EMPTY);

	/*等待send()和recv()出错释放信号灯*/
	semTake(semCmdLink,WAIT_FOREVER);

	/*获得信号灯,表示网络连接断开*/
	semDelete(semCmdLink);
	taskSpawn(TNAME_NETCLOSEALL,TPRI_NETCLOSEALL,0,USER_STACK_SIZE,(FUNCPTR)netCloseAll,
				MODE_NET_REINIT,0,0,0,0,0,0,0,0,0);
}
			



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值