/********************************************************************** 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); }