├── header ├── mempool │ ├── memblock.h │ ├── memunit.h │ ├── memblocklist.h │ ├── mempool.h │ └── fixmemorypool.h ├── commondata │ ├── dataInfo.h │ ├── commontype.h │ └── magicNum.h ├── commonfunction │ ├── signalHandleFun.h │ ├── netSocketFun.h │ └── localSocketFun.h ├── messagehandle │ ├── SendNewfdMsg.h │ ├── sendAlarmMsg.h │ ├── recvNewFdMsg.h │ ├── sendReqCloseMsg.h │ ├── recvcAndSendcMsgMsg.h │ ├── recvpAndSendcMsgMsg.h │ ├── handleAndRecvCloseMsg.h │ ├── recvAndSendReleaseMsg.h │ ├── recvAlarmAndSendMsgMsg.h │ ├── recvAndHandleReleaseMsg.h │ ├── messageHandle.h │ └── messageHandleInterface.h ├── globalDataControl.h ├── childProcess.h ├── childProcessInfo.h ├── handleEpollSocket.h ├── parentProcess.h ├── deviceProcess.h └── processManage.h ├── readme.txt ├── main.cpp ├── src ├── messagehandle │ ├── handleAndRecvCloseMsg.cpp │ ├── SendNewfdMsg.cpp │ ├── sendAlarmMsg.cpp │ ├── sendReqCloseMsg.cpp │ ├── recvAndHandleReleaseMsg.cpp │ ├── recvNewFdMsg.cpp │ ├── recvAlarmAndSendMsgMsg.cpp │ ├── recvAndSendReleaseMsg.cpp │ ├── recvpAndSendcMsgMsg.cpp │ ├── recvcAndSendcMsgMsg.cpp │ └── messageHandle.cpp ├── commonfunction │ ├── signalHandleFun.cpp │ ├── netSocketFun.cpp │ └── localSocketFun.cpp ├── globalDataControl.cpp ├── mempool │ ├── memblocklist.cpp │ └── mempool.cpp ├── childProcess.cpp ├── handleEpollSocket.cpp ├── deviceProcess.cpp ├── parentProcess.cpp └── processManage.cpp ├── .project └── .cproject /header/mempool/memblock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include"memunit.h" 3 | class MemBlock{ 4 | public: 5 | MemUnit *pUnit; 6 | MemBlock *next; 7 | }; -------------------------------------------------------------------------------- /header/mempool/memunit.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define UNITSIZE 64 4 | class MemBlock; 5 | 6 | struct MemUnit{ 7 | unsigned icount; 8 | MemBlock *pBlock; 9 | unsigned istart; 10 | }; 11 | typedef struct MemUnit MemUnit; 12 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | 1、逻辑上清晰:一个进程负责所有连接及共同数据,而每个子进程则只管与固定客户的通信 2 | 2、编程上简易:没个socket与固定的进程关联,不用考虑全局数据的同步,不易发生错误,而线程则不能与某个socket关联,如果要使用线程专有数据,则只能使用阻塞模式。 3 | 3、运行时安全:当某个进程崩溃时,不会影响其他进程的正常运行 4 | 4、各个连接比较独立,相互之间没有太多交互 5 | 5、可以将设备的socket放入到每个进程中,这样不需要全局数据,每个进程都可以负责接受设备的请求 6 | -------------------------------------------------------------------------------- /header/commondata/dataInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * dataInfo.h 3 | * 4 | * Created on: 2013-3-30 5 | * Author: keym 6 | */ 7 | 8 | #ifndef DATAINFO_H_ 9 | #define DATAINFO_H_ 10 | #include"commondata/commontype.h" 11 | 12 | class dataInfo{ 13 | public: 14 | char *_pdata;//要发送的数据(头+数据) 15 | size_t _size;//头+数据的大小 16 | }; 17 | 18 | #endif /* DATAINFO_H_ */ 19 | -------------------------------------------------------------------------------- /header/commonfunction/signalHandleFun.h: -------------------------------------------------------------------------------- 1 | /* 2 | * signalHandleFun.h 3 | * 4 | * Created on: 2013-1-25 5 | * Author: keym 6 | */ 7 | 8 | #ifndef SIGNALHANDLEFUN_H_ 9 | #define SIGNALHANDLEFUN_H_ 10 | #include 11 | 12 | typedef void Sigfunc(int); 13 | //添加信号处理函数 14 | Sigfunc *Signal(int signo, Sigfunc *func); 15 | void sig_cld(int signo); 16 | #endif /* SIGNALHANDLEFUN_H_ */ 17 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * main.cpp 3 | * 4 | * Created on: 2013-1-24 5 | * Author: keym 6 | */ 7 | 8 | #include"parentProcess.h" 9 | 10 | #include 11 | 12 | int main() 13 | { 14 | parentProcess p; 15 | try{ 16 | p.InitializeManage(4); 17 | p.CommunicationHandle(); 18 | } 19 | catch(std::exception &e) 20 | { 21 | std::cout<<"exception:"< 11 | 12 | namespace commontype{ 13 | //发送消息的头 14 | struct _messagehead{ 15 | size_t _type; 16 | size_t _size; 17 | }; 18 | typedef struct _messagehead headInfo; 19 | }; 20 | 21 | 22 | #endif /* COMMONTYPE_H_ */ 23 | -------------------------------------------------------------------------------- /header/messagehandle/SendNewfdMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * handleSendfdMsg.h 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | 8 | #ifndef SENDNEWFDMSG_H_ 9 | #define SENDNEWFDMSG_H_ 10 | #include"messageHandleInterface.h" 11 | class SendNewfdMsg : public messageHandleInterface{ 12 | private: 13 | virtual void packDataHead(); 14 | virtual char *packDataBody(); 15 | public: 16 | SendNewfdMsg():messageHandleInterface(){} 17 | }; 18 | 19 | #endif /* HANDLESENDFDMSG_H_ */ 20 | -------------------------------------------------------------------------------- /header/messagehandle/sendAlarmMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * sendAlarmMsg.h 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #ifndef SENDALARMMSG_H_ 9 | #define SENDALARMMSG_H_ 10 | 11 | #include"messageHandleInterface.h" 12 | class sendAlarmMsg : public messageHandleInterface{ 13 | private: 14 | virtual void packDataHead(); 15 | virtual char *packDataBody(); 16 | public: 17 | sendAlarmMsg():messageHandleInterface(){} 18 | }; 19 | 20 | #endif /* SENDALARMMSG_H_ */ 21 | -------------------------------------------------------------------------------- /header/commonfunction/netSocketFun.h: -------------------------------------------------------------------------------- 1 | /* 2 | * netSocketFun.h 3 | * 4 | * Created on: 2013-1-25 5 | * Author: keym 6 | */ 7 | 8 | #ifndef NETSOCKETFUN_H_ 9 | #define NETSOCKETFUN_H_ 10 | #include 11 | 12 | int ListenAndSetBlockNum(int fd, int backlog) ; 13 | int SetSocketNonblocking(int sock) ; //将文件描述符设置为非阻塞模式 14 | ssize_t RepeatRecv(int fd,char *buf,ssize_t bufsize); 15 | ssize_t RepeatSend(int fd,const char *buf,ssize_t bufsize); 16 | 17 | #endif /* NETSOCKETFUN_H_ */ 18 | -------------------------------------------------------------------------------- /header/messagehandle/recvNewFdMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * handleReqSendfdMsg.h 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | 8 | #ifndef RECVFDANDSENDMSGMSG_H_ 9 | #define RECVFDANDSENDMSGMSG_H_ 10 | #include"messageHandleInterface.h" 11 | class recvNewFdMsg : public messageHandleInterface{ 12 | private: 13 | virtual void packDataHead(); 14 | virtual char *packDataBody(); 15 | public: 16 | recvNewFdMsg():messageHandleInterface(){} 17 | }; 18 | 19 | #endif /* HANDLEREQSENDFDMSG_H_ */ 20 | -------------------------------------------------------------------------------- /header/messagehandle/sendReqCloseMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * handleReqCloseMsg.h 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | 8 | #ifndef SENDREQCLOSEMSG_H_ 9 | #define SENDREQCLOSEMSG_H_ 10 | #include"messageHandleInterface.h" 11 | class sendReqCloseMsg : public messageHandleInterface{ 12 | private: 13 | virtual void packDataHead(); 14 | virtual char *packDataBody(); 15 | public: 16 | sendReqCloseMsg():messageHandleInterface(){} 17 | }; 18 | 19 | #endif /* HANDLEREQCLOSEMSG_H_ */ 20 | -------------------------------------------------------------------------------- /header/commonfunction/localSocketFun.h: -------------------------------------------------------------------------------- 1 | /* 2 | * localSocketFun.h 3 | * 4 | * Created on: 2013-1-25 5 | * Author: keym 6 | */ 7 | 8 | #ifndef LOCALSOCKETFUN_H_ 9 | #define LOCALSOCKETFUN_H_ 10 | 11 | #include 12 | 13 | #define CONTROLLEN CMSG_LEN(sizeof(ssize_t)) 14 | 15 | //发送文件描述符 16 | int send_fd(int fd,int fd_to_send); 17 | int send_err(int fd,int errcode,const char *msg); 18 | //接收文件描述符 19 | int recv_fd(int fd,ssize_t (*userfunc)(int,const void *,size_t)); 20 | 21 | #endif /* LOCALSOCKETFUN_H_ */ 22 | -------------------------------------------------------------------------------- /header/messagehandle/recvcAndSendcMsgMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * handleSendMsgMsg.h 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | 8 | #ifndef RECVCANDSENDCMSGMSG_H_ 9 | #define RECVCANDSENDCMSGMSG_H_ 10 | 11 | #include"messageHandleInterface.h" 12 | class recvcAndSendcMsgMsg : public messageHandleInterface{ 13 | private: 14 | virtual void packDataHead(); 15 | virtual char *packDataBody(); 16 | public: 17 | recvcAndSendcMsgMsg():messageHandleInterface(){} 18 | }; 19 | 20 | #endif /* RECVCANDSENDCMSGMSG_H_ */ 21 | -------------------------------------------------------------------------------- /header/messagehandle/recvpAndSendcMsgMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * recvpAndSendcMsgMsg.h 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #ifndef RECVPANDSENDCMSGMSG_H_ 9 | #define RECVPANDSENDCMSGMSG_H_ 10 | 11 | #include"messageHandleInterface.h" 12 | class recvpAndSendcMsgMsg : public messageHandleInterface{ 13 | private: 14 | virtual void packDataHead(); 15 | virtual char *packDataBody(); 16 | public: 17 | recvpAndSendcMsgMsg():messageHandleInterface(){} 18 | }; 19 | 20 | #endif /* RECVPANDSENDCMSGMSG_H_ */ 21 | -------------------------------------------------------------------------------- /header/messagehandle/handleAndRecvCloseMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * handleAndRecvCloseMsg.h 3 | * 4 | * Created on: Mar 27, 2013 5 | * Author: keym 6 | */ 7 | 8 | #ifndef HANDLEANDRECVCLOSEMSG_H_ 9 | #define HANDLEANDRECVCLOSEMSG_H_ 10 | 11 | #include"messageHandleInterface.h" 12 | class handleAndRecvCloseMsg : public messageHandleInterface{ 13 | private: 14 | virtual void packDataHead(); 15 | virtual char *packDataBody(); 16 | public: 17 | handleAndRecvCloseMsg():messageHandleInterface(){} 18 | }; 19 | 20 | #endif /* HANDLEANDRECVCLOSEMSG_H_ */ 21 | -------------------------------------------------------------------------------- /header/messagehandle/recvAndSendReleaseMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * recvAndSendReleaseMsg.h 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #ifndef RECVANDSENDRELEASEMSG_H_ 9 | #define RECVANDSENDRELEASEMSG_H_ 10 | 11 | #include"messageHandleInterface.h" 12 | class recvAndSendReleaseMsg : public messageHandleInterface{ 13 | private: 14 | virtual void packDataHead(); 15 | virtual char *packDataBody(); 16 | public: 17 | recvAndSendReleaseMsg():messageHandleInterface(){} 18 | }; 19 | 20 | #endif /* RECVANDSENDRELEASEMSG_H_ */ 21 | -------------------------------------------------------------------------------- /header/messagehandle/recvAlarmAndSendMsgMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * recvAlarmAndSendMsgMsg.h 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #ifndef RECVALARMANDSENDMSGMSG_H_ 9 | #define RECVALARMANDSENDMSGMSG_H_ 10 | 11 | #include"messageHandleInterface.h" 12 | class recvAlarmAndSendMsgMsg : public messageHandleInterface{ 13 | private: 14 | virtual void packDataHead(); 15 | virtual char *packDataBody(); 16 | public: 17 | recvAlarmAndSendMsgMsg():messageHandleInterface(){} 18 | }; 19 | 20 | #endif /* RECVALARMANDSENDMSGMSG_H_ */ 21 | -------------------------------------------------------------------------------- /header/messagehandle/recvAndHandleReleaseMsg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * recvAndHandleReleaseMsg.h 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #ifndef RECVANDHANDLERELEASEMSG_H_ 9 | #define RECVANDHANDLERELEASEMSG_H_ 10 | 11 | #include"messageHandleInterface.h" 12 | class recvAndHandleReleaseMsg : public messageHandleInterface{ 13 | private: 14 | virtual void packDataHead(); 15 | virtual char *packDataBody(); 16 | public: 17 | recvAndHandleReleaseMsg():messageHandleInterface(){} 18 | }; 19 | 20 | #endif /* RECVANDHANDLERELEASEMSG_H_ */ 21 | -------------------------------------------------------------------------------- /header/globalDataControl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * globalDataControl.h 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #ifndef GLOBALDATACONTROL_H_ 9 | #define GLOBALDATACONTROL_H_ 10 | 11 | #include 12 | #include 13 | class globalDataControl{ 14 | private: 15 | std::map _mclientfdAndAlloc; 16 | size_t _uallocnum; 17 | public: 18 | globalDataControl():_uallocnum(0){} 19 | void AddFreeSockfd(const int sockfd); 20 | const int AllocFreeSockfd(); 21 | void ReleaseBusySockfd(const int sockfd); 22 | void DelCloseSockfd(const int sockfd); 23 | }; 24 | 25 | #endif /* GLOBALDATACONTROL_H_ */ 26 | -------------------------------------------------------------------------------- /src/messagehandle/handleAndRecvCloseMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * handleAndRecvCloseMsg.cpp 3 | * 4 | * Created on: Mar 27, 2013 5 | * Author: keym 6 | */ 7 | 8 | #include"messagehandle/handleAndRecvCloseMsg.h" 9 | #include"parentProcess.h" 10 | #include 11 | 12 | void handleAndRecvCloseMsg::packDataHead() 13 | { 14 | parentProcess *_tempuser = (parentProcess *)this->_uperuser; 15 | _tempuser->relEpollSocket(this->_recvSocketfd,INIT); 16 | this->phead->_type = magicnum::messagetype::NULLTYPENUM; 17 | } 18 | 19 | char *handleAndRecvCloseMsg::packDataBody() 20 | { 21 | this->_dataBodysize = 0; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /src/messagehandle/SendNewfdMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * handleSendfdMsg.cpp 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | #include"messagehandle/SendNewfdMsg.h" 8 | #include 9 | 10 | void SendNewfdMsg::packDataHead() 11 | { 12 | this->_sendSocketfd = this->_recvSocketfd; 13 | this->phead->_size = this->_dataBodysize; 14 | this->phead->_type = magicnum::messagetype::PCREQSENDFD; 15 | } 16 | 17 | char *SendNewfdMsg::packDataBody() 18 | { 19 | char *buf = this->getfreemem(sizeof(pid_t)); 20 | pid_t *pid = (pid_t*)buf; 21 | *pid = getpid(); 22 | this->_dataBodysize = sizeof(pid_t); 23 | return buf; 24 | } 25 | -------------------------------------------------------------------------------- /src/messagehandle/sendAlarmMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * sendAlarmMsg.cpp 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #include"messagehandle/sendAlarmMsg.h" 9 | #include"deviceProcess.h" 10 | #include 11 | 12 | void sendAlarmMsg::packDataHead() 13 | { 14 | deviceProcess *_tempuser = (deviceProcess *)this->_uperuser; 15 | this->_sendSocketfd = _tempuser->GetParentSocketfd(); 16 | 17 | this->phead->_size = this->_dataBodysize; 18 | this->phead->_type =magicnum::messagetype::DPSENDALARM; 19 | } 20 | 21 | char *sendAlarmMsg::packDataBody() 22 | { 23 | this->_dataBodysize = 0; 24 | return NULL; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/messagehandle/sendReqCloseMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * handleReqCloseMsg.cpp 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | #include"messagehandle/sendReqCloseMsg.h" 8 | #include"childProcess.h" 9 | #include 10 | 11 | void sendReqCloseMsg::packDataHead() 12 | { 13 | childProcess *_tempuser = (childProcess *)this->_uperuser; 14 | this->_sendSocketfd = _tempuser->GetSocketfd('p'); 15 | close(_tempuser->GetSocketfd('c')); 16 | this->phead->_size = this->_dataBodysize; 17 | this->phead->_type = magicnum::messagetype::CPREQCLOSED; 18 | } 19 | 20 | char *sendReqCloseMsg::packDataBody() 21 | { 22 | this->_dataBodysize = 0; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /src/messagehandle/recvAndHandleReleaseMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * recvAndHandleReleaseMsg.cpp 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #include"messagehandle/recvAndHandleReleaseMsg.h" 9 | #include"commonfunction/netSocketFun.h" 10 | #include"parentProcess.h" 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | void recvAndHandleReleaseMsg::packDataHead() 17 | { 18 | ((parentProcess *)this->_uperuser)->ReleaseSockfd(this->_recvSocketfd); 19 | this->phead->_type = magicnum::messagetype::NULLTYPENUM; 20 | } 21 | 22 | char *recvAndHandleReleaseMsg::packDataBody() 23 | { 24 | this->_dataBodysize = 0; 25 | return NULL; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /header/mempool/memblocklist.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include"memblock.h" 3 | 4 | #include 5 | 6 | class MemBlockList{ 7 | private: 8 | MemBlock *plist; 9 | size_t icount; 10 | public: 11 | MemBlockList():icount(0) 12 | { 13 | plist = NULL; 14 | } 15 | public: 16 | void createList(MemBlock * pmem,int num); 17 | void pushFront(MemBlock *block); 18 | MemBlock *popFront(); 19 | MemBlock *getBlock(size_t size); 20 | void deleteBlock(MemBlock *block); 21 | public: 22 | void test() 23 | { 24 | printf("icount:%d\nidata:",this->icount); 25 | MemBlock *temp = this->plist; 26 | while(temp != NULL) 27 | { 28 | if(temp->pUnit != NULL) 29 | { 30 | printf("%d,",temp->pUnit->icount); 31 | } 32 | temp = temp->next; 33 | } 34 | printf("\n"); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /header/messagehandle/messageHandle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * messagehandle.h 3 | * 4 | * Created on: 2013-1-31 5 | * Author: keym 6 | */ 7 | 8 | #ifndef MESSAGEHANDLE_H_ 9 | #define MESSAGEHANDLE_H_ 10 | #include 11 | #include 12 | //用来实现工厂模式 13 | class messageHandle{ 14 | private: 15 | std::map _mmsgHandle; 16 | private: 17 | messageHandleInterface *getMsgHandleInstance(unsigned type); 18 | public: 19 | static messageHandle* _singleInstance; 20 | static messageHandle *getInstance(); 21 | class Garbo{ 22 | public: 23 | ~Garbo() 24 | { 25 | if(messageHandle::_singleInstance != NULL) 26 | { 27 | delete messageHandle::_singleInstance; 28 | } 29 | } 30 | }; 31 | static Garbo release; 32 | public: 33 | messageHandle(); 34 | void msgHandle(void *recvbuf,int recvfd,void *uperuser); 35 | }; 36 | #endif /* MESSAGEHANDLE_H_ */ 37 | -------------------------------------------------------------------------------- /src/messagehandle/recvNewFdMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * handleReqSendfdMsg.cpp 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | #include"childProcess.h" 8 | 9 | #include"messagehandle/recvNewFdMsg.h" 10 | #include"commonfunction/netSocketFun.h" 11 | #include 12 | void recvNewFdMsg::packDataHead() 13 | { 14 | childProcess *_tempuser = (childProcess *)this->_uperuser; 15 | _tempuser->acceptClientSocket(); 16 | _tempuser->AddEpollSocket(_tempuser->GetSocketfd('c')); 17 | this->phead->_type = magicnum::messagetype::NULLTYPENUM; 18 | } 19 | 20 | char *recvNewFdMsg::packDataBody() 21 | { 22 | int readbytes; 23 | char *readbuf = this->getfreemem(this->_recvDatasize); 24 | if((readbytes=RepeatRecv(this->_recvSocketfd,readbuf,this->_recvDatasize)) < 0) 25 | { 26 | //这里可能是客户端关闭或出现错误 27 | return 0; 28 | } 29 | this->releaseFreemem(readbuf); 30 | this->_dataBodysize = 0; 31 | return NULL; 32 | } 33 | -------------------------------------------------------------------------------- /header/childProcess.h: -------------------------------------------------------------------------------- 1 | /* 2 | * childProcess.h 3 | * 4 | * Created on: 2013-1-30 5 | * Author: keym 6 | */ 7 | 8 | #ifndef CHILDPROCESS_H_ 9 | #define CHILDPROCESS_H_ 10 | #include"handleEpollSocket.h" 11 | 12 | #include 13 | 14 | class childProcess : protected handleEpollSocket{ 15 | private: 16 | int _parentSocket; 17 | int _clientSocket; 18 | public: 19 | void acceptClientSocket(); 20 | void AddEpollSocket(int socketfd) 21 | { 22 | handleEpollSocket::addEpollSocket(socketfd); 23 | } 24 | int GetSocketfd(char pOrc) 25 | { 26 | switch(pOrc) 27 | { 28 | case 'p': 29 | return this->_parentSocket; 30 | case 'c': 31 | return this->_clientSocket; 32 | default: 33 | assert(1 == 0); 34 | } 35 | } 36 | public: 37 | explicit childProcess(int parentfd):_parentSocket(parentfd){} 38 | void InitializeProcess(); 39 | void CommunicateHandle(); 40 | }; 41 | 42 | #endif /* CHILDPROCESS_H_ */ 43 | -------------------------------------------------------------------------------- /header/childProcessInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * childProcessInfo.h 3 | * 4 | * Created on: 2013-1-24 5 | * Author: keym 6 | */ 7 | 8 | #ifndef CHILDPROCESSINFO_H_ 9 | #define CHILDPROCESSINFO_H_ 10 | 11 | #include 12 | 13 | #include 14 | 15 | enum PROCESSSTATE{INIT = 0,BUSY,ERR}; 16 | 17 | class childProcessInfo{ 18 | private: 19 | int _communicateSocket; 20 | PROCESSSTATE _processState; 21 | pid_t _processId; 22 | public: 23 | explicit childProcessInfo(int socket,PROCESSSTATE state,pid_t pid) 24 | :_communicateSocket(socket),_processState(state),_processId(pid){} 25 | 26 | PROCESSSTATE GetProcessState(){return this->_processState;} 27 | void SetProcessState(PROCESSSTATE state){this->_processState = state;} 28 | int GetProcessSocket(){return this->_communicateSocket;} 29 | pid_t GetProcessPid(){return this->_processId;} 30 | //不要在析构或构造函数上使用一些可能产生错误的操作 31 | }; 32 | 33 | #endif /* CHILDPROCESSINFO_H_ */ 34 | -------------------------------------------------------------------------------- /src/messagehandle/recvAlarmAndSendMsgMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * recvAlarmAndSendMsgMsg.cpp 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #include"messagehandle/recvAlarmAndSendMsgMsg.h" 9 | #include"commonfunction/netSocketFun.h" 10 | #include"parentProcess.h" 11 | 12 | #include 13 | #include 14 | #include 15 | void recvAlarmAndSendMsgMsg::packDataHead() 16 | { 17 | int _allocfd = ((parentProcess *)this->_uperuser)->GetFreeSockfd(); 18 | if(_allocfd == magicnum::FAILIED) 19 | { 20 | this->phead->_type = magicnum::messagetype::NULLTYPENUM; 21 | return; 22 | } 23 | this->_sendSocketfd = _allocfd; 24 | 25 | this->phead->_size = this->_dataBodysize; 26 | this->phead->_type = magicnum::messagetype::PCMESSAGEPC; 27 | } 28 | 29 | char *recvAlarmAndSendMsgMsg::packDataBody() 30 | { 31 | char *buf = this->getfreemem(sizeof(pid_t)); 32 | pid_t *pid = (pid_t*)buf; 33 | *pid = getpid(); 34 | this->_dataBodysize = sizeof(pid_t); 35 | return buf; 36 | } 37 | 38 | -------------------------------------------------------------------------------- /header/handleEpollSocket.h: -------------------------------------------------------------------------------- 1 | /* 2 | * handleEpollSocket.h 3 | * 4 | * Created on: 2013-1-30 5 | * Author: keym 6 | */ 7 | 8 | #ifndef HANDLEEPOLLSOCKET_H_ 9 | #define HANDLEEPOLLSOCKET_H_ 10 | 11 | #include 12 | 13 | #include"commonfunction/localSocketFun.h" 14 | #include"commonfunction/netSocketFun.h" 15 | #include"commondata/magicNum.h" 16 | #include"commondata/dataInfo.h" 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | class handleEpollSocket{ 23 | protected: 24 | int _epfd; 25 | unsigned _maxNumOfEpollfd; 26 | std::deque _ddataToSend; 27 | private: 28 | void getEpollFdlimit(); 29 | void createEpollfd(); 30 | protected: 31 | handleEpollSocket():_maxNumOfEpollfd(magicnum::processmanage::MAXNUMPROCESS){} 32 | void initializeEpoll(); 33 | void addEpollSocket(int fd); 34 | public: 35 | void delEpollSocket(int fd); 36 | void modEpollSocket(int fd,bool rOrw); 37 | void packData(void *pdata); 38 | void sendData(int socket); 39 | }; 40 | 41 | #endif /* HANDLEEPOLLSOCKET_H_ */ 42 | -------------------------------------------------------------------------------- /src/messagehandle/recvAndSendReleaseMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * recvAndSendReleaseMsg.cpp 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #include"messagehandle/recvAndSendReleaseMsg.h" 9 | #include"commonfunction/netSocketFun.h" 10 | #include"childProcess.h" 11 | #include 12 | 13 | #include 14 | #include 15 | void recvAndSendReleaseMsg::packDataHead() 16 | { 17 | 18 | this->_sendSocketfd = ((childProcess *)this->_uperuser)->GetSocketfd('p'); 19 | this->phead->_size = this->_dataBodysize; 20 | this->phead->_type = magicnum::messagetype::CPRELEASECP; 21 | } 22 | 23 | char *recvAndSendReleaseMsg::packDataBody() 24 | { 25 | int readbytes; 26 | char *readbuf = this->getfreemem(this->_recvDatasize); 27 | if((readbytes=RepeatRecv(this->_recvSocketfd,readbuf,this->_recvDatasize)) < 0) 28 | { 29 | //这里可能是客户端关闭或出现错误 30 | return 0; 31 | } 32 | pid_t *temp = (pid_t *)readbuf; 33 | assert(*temp == getpid()); 34 | this->releaseFreemem(readbuf); 35 | this->_dataBodysize = 0; 36 | return NULL; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /src/messagehandle/recvpAndSendcMsgMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * recvpAndSendcMsgMsg.cpp 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | #include"messagehandle/recvpAndSendcMsgMsg.h" 8 | #include"commonfunction/netSocketFun.h" 9 | #include"childProcess.h" 10 | #include 11 | 12 | #include 13 | #include 14 | void recvpAndSendcMsgMsg::packDataHead() 15 | { 16 | this->_sendSocketfd = ((childProcess *)this->_uperuser)->GetSocketfd('c'); 17 | this->phead->_size = this->_dataBodysize; 18 | this->phead->_type = magicnum::messagetype::CCMESSAGECC; 19 | } 20 | 21 | char *recvpAndSendcMsgMsg::packDataBody() 22 | { 23 | int readbytes; 24 | char *readbuf = this->getfreemem(this->_recvDatasize); 25 | if((readbytes=RepeatRecv(this->_recvSocketfd,readbuf,this->_recvDatasize)) < 0) 26 | { 27 | //这里可能是客户端关闭或出现错误 28 | return 0; 29 | } 30 | this->releaseFreemem(readbuf); 31 | char *buf = this->getfreemem(sizeof(pid_t)); 32 | pid_t *pid = (pid_t*)buf; 33 | *pid = getpid(); 34 | this->_dataBodysize = sizeof(pid_t); 35 | return buf; 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/messagehandle/recvcAndSendcMsgMsg.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * handleSendMsgMsg.cpp 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | #include"messagehandle/recvcAndSendcMsgMsg.h" 8 | #include"commonfunction/netSocketFun.h" 9 | #include 10 | 11 | #include 12 | #include 13 | void recvcAndSendcMsgMsg::packDataHead() 14 | { 15 | this->_sendSocketfd = this->_recvSocketfd; 16 | 17 | this->phead->_size = this->_dataBodysize; 18 | this->phead->_type = magicnum::messagetype::CCRELEASECC; 19 | 20 | } 21 | 22 | char *recvcAndSendcMsgMsg::packDataBody() 23 | { 24 | int readbytes; 25 | char *readbuf = this->getfreemem(this->_recvDatasize); 26 | if((readbytes=RepeatRecv(this->_recvSocketfd,readbuf,this->_recvDatasize)) < 0) 27 | { 28 | //这里可能是客户端关闭或出现错误 29 | return 0; 30 | } 31 | pid_t *temp = (pid_t *)readbuf; 32 | assert(*temp == getpid()); 33 | this->releaseFreemem(readbuf); 34 | char *buf = this->getfreemem(sizeof(pid_t)); 35 | pid_t *pid = (pid_t*)buf; 36 | *pid = getpid(); 37 | this->_dataBodysize = sizeof(pid_t); 38 | return buf; 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/commonfunction/signalHandleFun.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * signalHandleFun.cpp 3 | * 4 | * Created on: 2013-1-25 5 | * Author: keym 6 | */ 7 | #include 8 | #include 9 | #include 10 | 11 | #include"commonfunction/signalHandleFun.h" 12 | 13 | #include 14 | #include 15 | 16 | //添加信号处理函数 17 | Sigfunc* Signal(int signo, Sigfunc* func) 18 | { 19 | struct sigaction act, oact; 20 | act.sa_handler = func; 21 | sigemptyset(&act.sa_mask); 22 | act.sa_flags = 0; 23 | if (signo == SIGALRM) { 24 | #ifdef SA_INTERRUPT 25 | act.sa_flags|=SA_INTERRUPT;//在处理指定信号时,屏蔽该信号 26 | #endif 27 | } else { 28 | #ifdef SA_RESTART 29 | act.sa_flags|=SA_RESTART; 30 | #endif 31 | } 32 | if (sigaction(signo, &act, &oact) < 0) 33 | return (SIG_ERR); 34 | return (oact.sa_handler); 35 | } 36 | 37 | //处理关闭子进程 38 | void sig_cld(int signo) 39 | { 40 | pid_t pid; 41 | while(1) 42 | { 43 | if((pid = waitpid(-1,NULL,WNOHANG)) <= 0) 44 | { 45 | break; 46 | } 47 | else 48 | { 49 | std::cout<<"sig_cld:"< 12 | #include"handleEpollSocket.h" 13 | #include"childProcessInfo.h" 14 | #include"globalDataControl.h" 15 | 16 | class parentProcess : protected handleEpollSocket{ 17 | private: 18 | int _netListenfd;//接受客户端连接的socket 19 | int _devicefd; 20 | std::deque _dnewConnectSocket; 21 | globalDataControl _cfdAndAlloc; 22 | private: 23 | void initializeListenfd(); 24 | void initializeChildProcessfd(int num); 25 | void acceptNewConnection(int newfd); 26 | void sendNewConnection(int sendfd); 27 | public: 28 | const int GetFreeSockfd() 29 | { 30 | return this->_cfdAndAlloc.AllocFreeSockfd(); 31 | } 32 | void ReleaseSockfd(const int sockfd) 33 | { 34 | this->_cfdAndAlloc.ReleaseBusySockfd(sockfd); 35 | } 36 | void relEpollSocket(int socket,PROCESSSTATE type); 37 | void InitializeManage(int num)throw(std::exception); 38 | void AddSocketToEpoll(int socket); 39 | void CommunicationHandle(); 40 | }; 41 | 42 | #endif /* PARENTPROCESS_H_ */ 43 | -------------------------------------------------------------------------------- /header/deviceProcess.h: -------------------------------------------------------------------------------- 1 | /* 2 | * deviceProcess.h 3 | * 4 | * Created on: Mar 27, 2013 5 | * Author: keym 6 | */ 7 | 8 | #ifndef DEVICEPROCESS_H_ 9 | #define DEVICEPROCESS_H_ 10 | 11 | #include"handleEpollSocket.h" 12 | 13 | class deviceProcess : protected handleEpollSocket{ 14 | private: 15 | int _netListenfd; 16 | int _parentfd; 17 | private: 18 | void initializeListenfd(); 19 | static deviceProcess *_singleInstance; 20 | class Garbo{//用于删除实例句柄 21 | public: 22 | ~Garbo() 23 | { 24 | if(deviceProcess::_singleInstance != NULL) 25 | { 26 | delete deviceProcess::_singleInstance; 27 | } 28 | } 29 | }; 30 | static Garbo release; 31 | public: 32 | static deviceProcess *GetInstance() 33 | { 34 | if(deviceProcess::_singleInstance == NULL) 35 | { 36 | deviceProcess::_singleInstance = new deviceProcess; 37 | deviceProcess::_singleInstance->initializeListenfd(); 38 | } 39 | return deviceProcess::_singleInstance; 40 | } 41 | public: 42 | const int GetParentSocketfd() 43 | { 44 | return this->_parentfd; 45 | } 46 | int GetSocketfdAndRun(); 47 | void CommunicationHandle(); 48 | 49 | }; 50 | 51 | #endif /* DEVICEPROCESS_H_ */ 52 | -------------------------------------------------------------------------------- /header/commondata/magicNum.h: -------------------------------------------------------------------------------- 1 | /* 2 | * magicNum.h 3 | * 4 | * Created on: 2013-1-25 5 | * Author: keym 6 | */ 7 | 8 | #ifndef MAGICNUM_H_ 9 | #define MAGICNUM_H_ 10 | #include 11 | //魔法数一定不要直接使用 12 | namespace magicnum{ 13 | 14 | const ssize_t SUCCESS = 0; 15 | const ssize_t FAILIED = -1; 16 | const ssize_t CLOSEED = -2; 17 | const size_t UNFIXMEMPOOLSIZE = 10000; 18 | const size_t MSGHEADSIZE = sizeof(size_t) * 2; 19 | 20 | namespace processmanage{ 21 | const size_t DIVISOR = 2; 22 | const size_t MAXNUMPROCESS = 4; 23 | const size_t MINNUMPROCESS = 2; 24 | }; 25 | 26 | namespace localsocketfun{ 27 | const size_t BUFFERSIZE = 2; 28 | }; 29 | 30 | namespace deviceprocess{ 31 | const size_t LISTENPORT = 5678; 32 | }; 33 | 34 | namespace parentprocess{ 35 | const size_t LISTNEPORT = 1234; 36 | const size_t LISTENBLOCKNUM = 10; 37 | const ssize_t EPOLLTIMEOUT = -1; 38 | }; 39 | 40 | namespace messagetype{ 41 | const size_t NULLTYPENUM = 1000; 42 | const size_t PCREQSENDFD = 1001;//发送描述符 43 | const size_t CPREQCLOSED = 2002; 44 | const size_t NULLSENDFDT = 3003; 45 | const size_t CCMESSAGECC = 4004;//客户间传递的消息 46 | const size_t CCREQCLOSED = 5005; 47 | const size_t NULLSENDALA = 6006; 48 | const size_t DPSENDALARM = 7007; 49 | const size_t PCMESSAGEPC = 8008; 50 | const size_t CCRELEASECC = 9009; 51 | const size_t CPRELEASECP = 0110; 52 | }; 53 | 54 | }; 55 | 56 | #endif /* MAGICNUM_H_ */ 57 | -------------------------------------------------------------------------------- /header/mempool/mempool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include"memblocklist.h" 3 | #include"commondata/magicNum.h" 4 | 5 | //此内存池不可扩充 6 | class MemPool{ 7 | private: 8 | void *pbuf; 9 | int isize; 10 | private: 11 | int iusedsize; 12 | int itotalsize; 13 | private: 14 | int iunitcount; 15 | MemUnit *punit; 16 | void *pmem; 17 | size_t imemcount; 18 | MemBlockList blockpool; 19 | MemBlockList freeblock; 20 | private: 21 | static MemPool *_instance; 22 | class release{ 23 | public: 24 | ~release() 25 | { 26 | if(MemPool::_instance != NULL) 27 | { 28 | delete MemPool::_instance; 29 | MemPool::_instance = NULL; 30 | } 31 | } 32 | }; 33 | static release rel; 34 | public: 35 | static MemPool *getInstance() 36 | { 37 | if(MemPool::_instance == NULL) 38 | { 39 | MemPool::_instance = new MemPool(new char[magicnum::UNFIXMEMPOOLSIZE],magicnum::UNFIXMEMPOOLSIZE); 40 | } 41 | return MemPool::_instance; 42 | } 43 | MemPool(void *mem,int size); 44 | public: 45 | void *getMem(size_t size); 46 | void freeMem(void *mem); 47 | public: 48 | void test() 49 | { 50 | printf("...........................\n"); 51 | printf("itotalsize:%d,iunitcount:%d,imemcount:%d\n",this->itotalsize,this->iunitcount,this->imemcount); 52 | this->blockpool.test(); 53 | this->freeblock.test(); 54 | printf("...........................\n"); 55 | } 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /src/globalDataControl.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * globalDataControl.cpp 3 | * 4 | * Created on: Mar 28, 2013 5 | * Author: keym 6 | */ 7 | 8 | #include"globalDataControl.h" 9 | #include"commondata/magicNum.h" 10 | 11 | #include 12 | #include 13 | 14 | void globalDataControl::AddFreeSockfd(const int sockfd) 15 | { 16 | this->_mclientfdAndAlloc[sockfd] = true; 17 | } 18 | 19 | const int globalDataControl::AllocFreeSockfd() 20 | { 21 | std::map::iterator _iter = this->_mclientfdAndAlloc.begin(); 22 | while(_iter != this->_mclientfdAndAlloc.end()) 23 | { 24 | if(_iter->second) 25 | { 26 | ++ this->_uallocnum; 27 | std::cout<<"allocnum:"<_uallocnum<second = false; 29 | return _iter->first; 30 | } 31 | ++ _iter; 32 | } 33 | return magicnum::FAILIED; 34 | } 35 | 36 | void globalDataControl::ReleaseBusySockfd(int sockfd) 37 | { 38 | std::map::iterator _iter = this->_mclientfdAndAlloc.find(sockfd); 39 | assert(_iter != this->_mclientfdAndAlloc.end()); 40 | _iter->second = true; 41 | -- this->_uallocnum; 42 | std::cout<<"allocnum:"<_uallocnum<::iterator _iter = this->_mclientfdAndAlloc.find(sockfd); 48 | //assert(_iter != this->_mclientfdAndAlloc.end()); 49 | if(_iter == this->_mclientfdAndAlloc.end()) 50 | { 51 | return; 52 | } 53 | if(!_iter->second) 54 | { 55 | -- this->_uallocnum; 56 | } 57 | this->_mclientfdAndAlloc.erase(_iter); 58 | std::cout<<"current mapsize:"<_mclientfdAndAlloc.size()< 3 | 4 | void MemBlockList::createList(MemBlock *pmem,int num) 5 | { 6 | assert(pmem != NULL && num != 0); 7 | this->plist = pmem; 8 | int i; 9 | for(i = 1;i < num;++ i) 10 | { 11 | this->plist[i - 1].next = &this->plist[i]; 12 | this->plist[i - 1].pUnit = NULL; 13 | } 14 | this->plist[num - 1].pUnit = NULL; 15 | this->plist[num - 1].next = NULL; 16 | this->icount = num; 17 | } 18 | 19 | MemBlock *MemBlockList::popFront() 20 | { 21 | if(this->plist == NULL) 22 | { 23 | return NULL; 24 | } 25 | MemBlock *temp = this->plist; 26 | this->plist = this->plist->next; 27 | -- this->icount; 28 | return temp; 29 | } 30 | 31 | void MemBlockList::pushFront(MemBlock *block) 32 | { 33 | assert(block != NULL); 34 | if(this->plist == NULL) 35 | { 36 | this->plist = block; 37 | block->next = NULL; 38 | } 39 | else 40 | { 41 | block->next = this->plist; 42 | this->plist = block; 43 | } 44 | ++ this->icount; 45 | } 46 | 47 | void MemBlockList::deleteBlock(MemBlock *block) 48 | { 49 | assert(this->plist != NULL && block != NULL); 50 | if(block == this->plist) 51 | { 52 | this->plist = this->plist->next; 53 | } 54 | else 55 | { 56 | MemBlock *pre = this->plist; 57 | MemBlock *cur = NULL; 58 | while(pre != NULL) 59 | { 60 | cur = pre->next; 61 | if(block == cur) 62 | { 63 | cur->pUnit = NULL; 64 | pre->next = cur->next; 65 | break; 66 | } 67 | pre = cur; 68 | } 69 | } 70 | -- this->icount; 71 | } 72 | 73 | MemBlock *MemBlockList::getBlock(size_t size) 74 | { 75 | MemBlock *temp = this->plist; 76 | while(temp != NULL) 77 | { 78 | if(temp->pUnit->icount * UNITSIZE >= size) 79 | { 80 | return temp; 81 | } 82 | temp = temp->next; 83 | } 84 | return temp; 85 | } 86 | -------------------------------------------------------------------------------- /header/processManage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * processManage.h 3 | * 4 | * Created on: 2013-1-24 5 | * Author: keym 6 | */ 7 | 8 | #ifndef PROCESSMANAGE_H_ 9 | #define PROCESSMANAGE_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include"childProcessInfo.h" 15 | #include"commonfunction/signalHandleFun.h" 16 | #include"commondata/magicNum.h" 17 | 18 | #include 19 | typedef std::vector::iterator vectorIterType; 20 | class parentProcess; 21 | 22 | class processManage{ 23 | private: 24 | std::vector _vProcessInfo;//子进程数据 25 | std::map _mProcessSocketAndIndex;//socket与数据直接联系 26 | unsigned _uTotalNumOfProcess;//子进程总数 27 | unsigned _uNumOfRunningProcess;//接受客户端链接的子进程总数 28 | unsigned _uMaxNumOfProcess;//可以创建的最大子进程总数 29 | unsigned _uMinNumOfProcess;//可以创建的最小的子进程总数 30 | static processManage *_singleInstance; 31 | class Garbo{//用于删除实例句柄 32 | public: 33 | ~Garbo() 34 | { 35 | if(processManage::_singleInstance != NULL) 36 | { 37 | delete processManage::_singleInstance; 38 | } 39 | } 40 | }; 41 | static Garbo release; 42 | public: 43 | static processManage *GetInstance() 44 | { 45 | if(processManage::_singleInstance == NULL) 46 | { 47 | processManage::_singleInstance = new processManage; 48 | processManage::_singleInstance->InitializeManage(); 49 | } 50 | return processManage::_singleInstance; 51 | } 52 | private: 53 | explicit processManage():_uTotalNumOfProcess(0), 54 | _uNumOfRunningProcess(0),_uMaxNumOfProcess(magicnum::processmanage::MAXNUMPROCESS), 55 | _uMinNumOfProcess(magicnum::processmanage::MINNUMPROCESS){} 56 | processManage(const processManage&); 57 | processManage& operator=(const processManage&);//不去定义 58 | ~processManage() 59 | { 60 | this->releaseAllData(); 61 | } 62 | private: 63 | void getSystemLimit();//获取系统的最大进程数 64 | void InitializeManage()//初始化操作:获取系统最大进程数,注册信号 65 | { 66 | getSystemLimit(); 67 | if(Signal(SIGCHLD,sig_cld)==SIG_ERR) 68 | { 69 | throw std::exception(); 70 | } 71 | } 72 | void releaseAllData();//释放所有数据 73 | void createSingleProcess();//创建一个子进程 74 | void moveErrorProcessToTail();//将_vProcessInfo前面的err类型的数据移动到后面 75 | public: 76 | void CreateAllProcess(unsigned num,parentProcess *pobject) throw(std::exception);//创建指定数目的进程 77 | int OccupyProcessToClient(parentProcess *pobject);//将一个进程分配给一个客户 78 | int ReleaseProcess(int socket,PROCESSSTATE type);//释放一个进程 79 | }; 80 | 81 | #endif /* PROCESSMANAGE_H_ */ 82 | -------------------------------------------------------------------------------- /src/messagehandle/messageHandle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * messageHandle.cpp 3 | * 4 | * Created on: 2013-2-1 5 | * Author: keym 6 | */ 7 | #include"messagehandle/messageHandle.h" 8 | #include"commondata/magicNum.h" 9 | #include"messagehandle/SendNewfdMsg.h" 10 | #include"messagehandle/recvNewFdMsg.h" 11 | #include"messagehandle/recvcAndSendcMsgMsg.h" 12 | #include"messagehandle/sendReqCloseMsg.h" 13 | #include"messagehandle/handleAndRecvCloseMsg.h" 14 | #include"messagehandle/sendAlarmMsg.h" 15 | #include"messagehandle/recvAlarmAndSendMsgMsg.h" 16 | #include"messagehandle/recvpAndSendcMsgMsg.h" 17 | #include"messagehandle/recvAndSendReleaseMsg.h" 18 | #include"messagehandle/recvAndHandleReleaseMsg.h" 19 | 20 | #include 21 | messageHandle* messageHandle::_singleInstance = NULL; 22 | 23 | messageHandle::messageHandle() 24 | { 25 | this->_mmsgHandle[magicnum::messagetype::NULLSENDFDT] = new SendNewfdMsg; 26 | this->_mmsgHandle[magicnum::messagetype::PCREQSENDFD] = new recvNewFdMsg; 27 | this->_mmsgHandle[magicnum::messagetype::CCMESSAGECC] = new recvcAndSendcMsgMsg; 28 | this->_mmsgHandle[magicnum::messagetype::CCREQCLOSED] = new sendReqCloseMsg; 29 | this->_mmsgHandle[magicnum::messagetype::CPREQCLOSED] = new handleAndRecvCloseMsg; 30 | this->_mmsgHandle[magicnum::messagetype::NULLSENDALA] = new sendAlarmMsg; 31 | this->_mmsgHandle[magicnum::messagetype::DPSENDALARM] = new recvAlarmAndSendMsgMsg; 32 | this->_mmsgHandle[magicnum::messagetype::PCMESSAGEPC] = new recvpAndSendcMsgMsg; 33 | this->_mmsgHandle[magicnum::messagetype::CCRELEASECC] = new recvAndSendReleaseMsg; 34 | this->_mmsgHandle[magicnum::messagetype::CPRELEASECP] = new recvAndHandleReleaseMsg; 35 | } 36 | 37 | void messageHandle::msgHandle(void *recvbuf,int recvfd,void *uperuser) 38 | { 39 | commontype::headInfo *phead = (commontype::headInfo*)recvbuf; 40 | messageHandleInterface *_instance = this->getMsgHandleInstance(phead->_type); 41 | _instance->HandleMsg(phead->_size,recvfd,uperuser); 42 | } 43 | 44 | messageHandleInterface *messageHandle::getMsgHandleInstance(unsigned type) 45 | { 46 | std::map::iterator _iter = this->_mmsgHandle.find(type); 47 | assert(_iter != this->_mmsgHandle.end()); 48 | return _iter->second; 49 | } 50 | 51 | messageHandle *messageHandle::getInstance() 52 | { 53 | if(messageHandle::_singleInstance == NULL) 54 | { 55 | messageHandle::_singleInstance = new messageHandle; 56 | } 57 | return messageHandle::_singleInstance; 58 | } 59 | -------------------------------------------------------------------------------- /src/childProcess.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * childProcess.cpp 3 | * 4 | * Created on: 2013-1-30 5 | * Author: keym 6 | */ 7 | #include"childProcess.h" 8 | #include"commondata/commontype.h" 9 | #include"messagehandle/messageHandle.h" 10 | #include"commondata/magicNum.h" 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | static void packReqCloseMsg(void *buffer); 19 | 20 | 21 | void childProcess::acceptClientSocket() 22 | { 23 | if((this->_clientSocket = recv_fd(this->_parentSocket,write)) == magicnum::FAILIED) 24 | { 25 | std::cerr<<"childProcess::acceptClientSocket:recv_fd"<_parentSocket); 34 | } 35 | 36 | void childProcess::CommunicateHandle() 37 | { 38 | struct epoll_event events[this->_maxNumOfEpollfd + 1]; 39 | std::deque _dPid; 40 | int readbytes; 41 | char readbuf[magicnum::MSGHEADSIZE]; 42 | for(;;) 43 | { 44 | int nfds; 45 | if((nfds=epoll_wait(_epfd,events,this->_maxNumOfEpollfd,magicnum::parentprocess::EPOLLTIMEOUT)) <= 0) 46 | { 47 | if (errno != EINTR) 48 | { 49 | std::cerr<<"parentProcess::CommunicationHandle:epoll_wait"<msgHandle(readbuf,events[i].data.fd,this); 70 | } 71 | else if(events[i].events&EPOLLOUT) 72 | { 73 | //通知的顺序与投递的顺序相同 74 | handleEpollSocket::sendData(events[i].data.fd); 75 | handleEpollSocket::modEpollSocket(events[i].data.fd,false); 76 | } 77 | else if((events[i].events&EPOLLHUP)||(events[i].events&EPOLLERR)) 78 | { 79 | throw std::exception(); 80 | } 81 | } 82 | } 83 | } 84 | 85 | static void packReqCloseMsg(void *buffer) 86 | { 87 | commontype::headInfo* _head = (commontype::headInfo *)buffer; 88 | _head->_type = magicnum::messagetype::CCREQCLOSED; 89 | _head->_size = 0; 90 | } 91 | -------------------------------------------------------------------------------- /src/commonfunction/netSocketFun.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * netSocketFun.cpp 3 | * 4 | * Created on: 2013-1-25 5 | * Author: keym 6 | */ 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include"commondata/magicNum.h" 14 | #include"commonfunction/signalHandleFun.h" 15 | 16 | #include 17 | #include 18 | 19 | int ListenAndSetBlockNum(int fd, int backlog) 20 | { 21 | char *ptr; 22 | if ((ptr = getenv("LISTENQ")) != NULL) 23 | { 24 | backlog = atoi(ptr); 25 | } 26 | if (listen(fd, backlog) < 0) 27 | { 28 | //perror("listen error:"); 29 | return magicnum::FAILIED; 30 | } 31 | return magicnum::SUCCESS; 32 | } 33 | 34 | int SetSocketNonblocking(int sock) //将文件描述符设置为非阻塞模式 35 | { 36 | int opts; 37 | if((opts=fcntl(sock,F_GETFL)<0)){ 38 | //perror("fcntl get"); 39 | return magicnum::FAILIED; 40 | } 41 | opts=opts|O_NONBLOCK; 42 | if(fcntl(sock,F_SETFL,opts)<0){ 43 | //perror("fcntl set"); 44 | return magicnum::FAILIED; 45 | } 46 | return magicnum::SUCCESS; 47 | } 48 | 49 | //当socket为阻塞形式时,采用alarm进行超时功能,如果为非阻塞形式不要采用,容易引起错误 50 | ssize_t RepeatRecv(int fd,char *buf,ssize_t bufsize) 51 | { 52 | ssize_t readbytes = 0; 53 | ssize_t remnantbytes = bufsize; 54 | char *pbuf = buf; 55 | while(remnantbytes > 0) 56 | { 57 | readbytes = recv(fd,pbuf,remnantbytes,0); 58 | if(readbytes <= 0)//0:对方关闭;<0:发生错误 59 | { 60 | if(readbytes == 0) 61 | { 62 | return magicnum::CLOSEED; 63 | } 64 | if(errno == EAGAIN || errno == EINTR)//EAGAIN:缓存无数据;EINTR:系统中断 65 | { 66 | //printf("buffer no data\n");//缓存区已无数据可读 67 | readbytes = 0; 68 | continue; 69 | } 70 | //perror("recv"); 71 | return magicnum::FAILIED; 72 | } 73 | remnantbytes -= readbytes;//发送部分数据 74 | pbuf += readbytes; 75 | } 76 | return remnantbytes; 77 | } 78 | 79 | ssize_t RepeatSend(int fd,const char *buf,ssize_t bufsize) 80 | { 81 | ssize_t sendbytes = 0; 82 | ssize_t remnantbytes = bufsize; 83 | const char *pbuf = buf; 84 | while(remnantbytes > 0) 85 | { 86 | sendbytes = send(fd,pbuf,remnantbytes,0); 87 | if(sendbytes <= 0) 88 | { 89 | if(errno==EINTR || errno==EAGAIN) 90 | { 91 | printf("block later..\n");//缓存区暂时已满,所以等待一会再次读取 92 | sendbytes = 0; 93 | continue; 94 | } 95 | return magicnum::FAILIED; 96 | } 97 | remnantbytes -= sendbytes;//发送部分数据 98 | pbuf += sendbytes; 99 | } 100 | return remnantbytes; 101 | } 102 | -------------------------------------------------------------------------------- /header/messagehandle/messageHandleInterface.h: -------------------------------------------------------------------------------- 1 | /* 2 | * messageHandleInterface.h 3 | * 4 | * Created on: 2013-1-31 5 | * Author: keym 6 | */ 7 | 8 | #ifndef MESSAGEHANDLEINTERFACE_H_ 9 | #define MESSAGEHANDLEINTERFACE_H_ 10 | #include"commondata/dataInfo.h" 11 | #include"commondata/magicNum.h" 12 | #include"commonfunction/netSocketFun.h" 13 | #include"mempool/fixmemorypool.h" 14 | #include"mempool/mempool.h" 15 | #include"../handleEpollSocket.h" 16 | #include 17 | //所有信息处理类的父类 18 | class messageHandleInterface{ 19 | protected: 20 | unsigned _dataBodysize; 21 | unsigned _recvDatasize; 22 | void *_uperuser; 23 | int _recvSocketfd; 24 | int _sendSocketfd; 25 | commontype::headInfo *phead; 26 | protected: 27 | messageHandleInterface():_uperuser(NULL) 28 | { 29 | this->phead = new commontype::headInfo; 30 | } 31 | virtual void packDataHead() = 0; 32 | virtual char *packDataBody() = 0; 33 | 34 | char *getfreemem(size_t size) 35 | { 36 | return (char*)MemPool::getInstance()->getMem(size); 37 | } 38 | 39 | void releaseFreemem(void *pmem) 40 | { 41 | MemPool::getInstance()->freeMem(pmem); 42 | } 43 | 44 | void mergeDataHeadAndBody() 45 | { 46 | char *pbody = this->packDataBody();//顺序不能换 47 | this->packDataHead(); 48 | 49 | if(this->phead->_type == magicnum::messagetype::NULLTYPENUM) 50 | { 51 | return; 52 | } 53 | dataInfo *pdataInfo = new dataInfo; 54 | //dataInfo *pdataInfo = fixmemorypool::getInstance()->mem_pool_alloc(); 55 | //pdataInfo->_pdata = new char[sizeof(commontype::headInfo) + this->_dataBodysize]; 56 | pdataInfo->_pdata = (char *)MemPool::getInstance()->getMem(sizeof(commontype::headInfo) + this->_dataBodysize); 57 | memcpy(pdataInfo->_pdata,phead,sizeof(commontype::headInfo)); 58 | memset(this->phead,0,sizeof(commontype::headInfo)); 59 | if(this->_dataBodysize != 0) 60 | { 61 | memcpy(pdataInfo->_pdata + sizeof(commontype::headInfo),pbody,this->_dataBodysize); 62 | this->releaseFreemem(pbody); 63 | } 64 | pdataInfo->_size = sizeof(commontype::headInfo) + this->_dataBodysize; 65 | 66 | handleEpollSocket *_tempuser = (handleEpollSocket *)this->_uperuser; 67 | _tempuser->packData(pdataInfo); 68 | _tempuser->modEpollSocket(this->_sendSocketfd,true); 69 | } 70 | public: 71 | void HandleMsg(unsigned size,int recvfd,void *uperuser) 72 | { 73 | this->_recvDatasize = size; 74 | this->_recvSocketfd = recvfd; 75 | this->_uperuser = uperuser; 76 | mergeDataHeadAndBody(); 77 | } 78 | public: 79 | virtual ~messageHandleInterface() 80 | { 81 | if(this->phead != NULL) 82 | { 83 | delete this->phead; 84 | } 85 | } 86 | }; 87 | 88 | #endif /* MESSAGEHANDLEINTERFACE_H_ */ 89 | -------------------------------------------------------------------------------- /src/handleEpollSocket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * handleEpollSocket.cpp 3 | * 4 | * Created on: 2013-1-30 5 | * Author: keym 6 | */ 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include"handleEpollSocket.h" 15 | #include"commondata/commontype.h" 16 | #include"mempool/fixmemorypool.h" 17 | #include"mempool/mempool.h" 18 | 19 | static bool flag = true; 20 | 21 | void handleEpollSocket::getEpollFdlimit() 22 | { 23 | rlimit limit; 24 | getrlimit(RLIMIT_FSIZE,&limit); 25 | if(limit.rlim_cur > magicnum::processmanage::MAXNUMPROCESS) 26 | { 27 | this->_maxNumOfEpollfd = limit.rlim_cur; 28 | } 29 | this->_maxNumOfEpollfd = 2048; 30 | //描述符数目不能太大,有限制 31 | } 32 | 33 | void handleEpollSocket::createEpollfd() 34 | { 35 | if((this->_epfd=epoll_create(this->_maxNumOfEpollfd))<0) 36 | { 37 | perror("epoll_create:"); 38 | std::cerr<<"parentProcess::initializeListenfdAndEpollfd:epoll_create"<_maxNumOfEpollfd<_ddataToSend.push_back((dataInfo*)pdata); 83 | } 84 | 85 | void handleEpollSocket::sendData(int sendfd) 86 | { 87 | dataInfo *pdataInfo = this->_ddataToSend[0]; 88 | this->_ddataToSend.pop_front(); 89 | if(RepeatSend(sendfd,pdataInfo->_pdata,pdataInfo->_size) == magicnum::FAILIED) 90 | { 91 | if(flag) 92 | { 93 | flag = false; 94 | perror("handleEpollSocket::sendData"); 95 | } 96 | } 97 | //delete []pdataInfo->_pdata; 98 | MemPool::getInstance()->freeMem(pdataInfo->_pdata); 99 | delete pdataInfo; 100 | //fixmemorypool::getInstance()->mem_pool_release(pdataInfo); 101 | } 102 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | MultiplyProcessServer 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?children? 14 | ?name?=outputEntries\|?children?=?name?=entry\\\\\\\|\\\|?name?=entry\\\\\\\|\\\|\|| 15 | 16 | 17 | ?name? 18 | 19 | 20 | 21 | org.eclipse.cdt.make.core.append_environment 22 | true 23 | 24 | 25 | org.eclipse.cdt.make.core.autoBuildTarget 26 | all 27 | 28 | 29 | org.eclipse.cdt.make.core.buildArguments 30 | 31 | 32 | 33 | org.eclipse.cdt.make.core.buildCommand 34 | make 35 | 36 | 37 | org.eclipse.cdt.make.core.buildLocation 38 | ${workspace_loc:/MultiplyProcessServer/Debug} 39 | 40 | 41 | org.eclipse.cdt.make.core.cleanBuildTarget 42 | clean 43 | 44 | 45 | org.eclipse.cdt.make.core.contents 46 | org.eclipse.cdt.make.core.activeConfigSettings 47 | 48 | 49 | org.eclipse.cdt.make.core.enableAutoBuild 50 | false 51 | 52 | 53 | org.eclipse.cdt.make.core.enableCleanBuild 54 | true 55 | 56 | 57 | org.eclipse.cdt.make.core.enableFullBuild 58 | true 59 | 60 | 61 | org.eclipse.cdt.make.core.fullBuildTarget 62 | all 63 | 64 | 65 | org.eclipse.cdt.make.core.stopOnError 66 | true 67 | 68 | 69 | org.eclipse.cdt.make.core.useDefaultBuildCmd 70 | true 71 | 72 | 73 | 74 | 75 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 76 | 77 | 78 | 79 | 80 | 81 | org.eclipse.cdt.core.cnature 82 | org.eclipse.cdt.core.ccnature 83 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 84 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/commonfunction/localSocketFun.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * localSocketFun.cpp 3 | * 4 | * Created on: 2013-1-25 5 | * Author: keym 6 | */ 7 | #include"commonfunction/localSocketFun.h" 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | #include"commondata/magicNum.h" 17 | 18 | #include 19 | 20 | static struct cmsghdr *cmptr = NULL; 21 | 22 | int send_fd(int fd,int fd_to_send) 23 | { 24 | struct iovec iov[1]; 25 | struct msghdr msg; 26 | char buf[magicnum::localsocketfun::BUFFERSIZE]; 27 | iov[0].iov_base=buf; 28 | iov[0].iov_len=2; 29 | msg.msg_iov=iov; 30 | msg.msg_iovlen=1; 31 | msg.msg_name=NULL; 32 | msg.msg_namelen=0; 33 | if(fd_to_send<0){ 34 | msg.msg_control=NULL; 35 | msg.msg_controllen=0; 36 | buf[1]=-fd_to_send; 37 | if(buf[1]==0) 38 | buf[1]=1; 39 | }else{ 40 | if(cmptr == NULL && ((cmptr = (cmsghdr*)malloc(CONTROLLEN)) == NULL)) 41 | return magicnum::FAILIED; 42 | cmptr->cmsg_level=SOL_SOCKET; 43 | cmptr->cmsg_type=SCM_RIGHTS; 44 | cmptr->cmsg_len=CONTROLLEN; 45 | msg.msg_control=cmptr; 46 | msg.msg_controllen=CONTROLLEN; 47 | *(int*)CMSG_DATA(cmptr)=fd_to_send; 48 | buf[1]=0; 49 | } 50 | buf[0]=0; 51 | if(sendmsg(fd,&msg,0)!=2) 52 | return magicnum::FAILIED; 53 | return magicnum::SUCCESS; 54 | } 55 | 56 | int send_err(int fd,int errcode,const char *msg) 57 | { 58 | int n; 59 | if((n=strlen(msg))>0) 60 | if(write(fd,msg,n)!=n) 61 | return magicnum::FAILIED; 62 | if(errcode>=0) 63 | errcode=-1; 64 | if(send_fd(fd,errcode)<0) 65 | return magicnum::FAILIED; 66 | return magicnum::SUCCESS; 67 | } 68 | 69 | int recv_fd(int fd,ssize_t (*userfunc)(int,const void *,size_t)) 70 | { 71 | int newfd,nr,status; 72 | char *ptr; 73 | char buf[magicnum::localsocketfun::BUFFERSIZE]; 74 | struct iovec iov[1]; 75 | struct msghdr msg; 76 | status=-1; 77 | for(;;) 78 | { 79 | iov[0].iov_base=buf; 80 | iov[0].iov_len=sizeof(buf); 81 | msg.msg_iov=iov; 82 | msg.msg_iovlen=1; 83 | msg.msg_name=NULL; 84 | msg.msg_namelen=0; 85 | if(cmptr==NULL&&(cmptr=(cmsghdr*)malloc(CONTROLLEN))==NULL) 86 | { 87 | return magicnum::FAILIED; 88 | } 89 | msg.msg_control=cmptr; 90 | msg.msg_controllen=CONTROLLEN; 91 | if((nr=recvmsg(fd,&msg,0))<0) 92 | { 93 | if(errno == EAGAIN || errno == EINTR)//EAGAIN:缓存无数据;EINTR:系统中断 94 | { 95 | //printf("buffer no data\n");//缓存区已无数据可读 96 | //readbytes = 0; 97 | continue; 98 | } 99 | perror("recvmsg"); 100 | //perror("recv"); 101 | return magicnum::FAILIED; 102 | } 103 | else if(nr==0) 104 | { 105 | printf("connection closed by server\n"); 106 | return magicnum::FAILIED; 107 | } 108 | for(ptr=buf;ptr<&buf[nr];) 109 | { 110 | if(*ptr++==0){ 111 | assert(ptr == &buf[nr-1]); 112 | status=*ptr&0xFF; 113 | if(status==0) 114 | { 115 | if(msg.msg_controllen!=CONTROLLEN) 116 | { 117 | printf("status=0,but no fd\n"); 118 | return magicnum::FAILIED; 119 | } 120 | newfd=*(int*)CMSG_DATA(cmptr); 121 | } 122 | else 123 | { 124 | newfd=-status; 125 | } 126 | nr=-2; 127 | } 128 | } 129 | if(nr > 0 && (*userfunc)(STDERR_FILENO,buf,nr)!=nr) 130 | { 131 | return magicnum::FAILIED; 132 | } 133 | if(status>=0) 134 | { 135 | return(newfd); 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /header/mempool/fixmemorypool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * fixmemorypool.h 3 | * 4 | * Created on: 2013-3-30 5 | * Author: keym 6 | */ 7 | 8 | #ifndef FIXMEMORYPOOL_H_ 9 | #define FIXMEMORYPOOL_H_ 10 | 11 | #include 12 | #include 13 | 14 | template 15 | union mem_node{ 16 | type node; 17 | union mem_node *next; 18 | }; 19 | 20 | template 21 | struct mem_block{ 22 | mem_node *head; 23 | mem_node *tail; 24 | struct mem_block *next; 25 | }; 26 | 27 | template 28 | class fixmemorypool{ 29 | private: 30 | enum {MAXNUM = 2}; 31 | static fixmemorypool *Instance; 32 | fixmemorypool(int num = MAXNUM):head(NULL),tail(NULL),nhead(NULL),total(0),left(0),block_size(num){} 33 | 34 | class release{ 35 | public: 36 | ~release() 37 | { 38 | if(Instance != NULL) 39 | { 40 | delete Instance; 41 | Instance = NULL; 42 | } 43 | } 44 | }; 45 | static release rel; 46 | private: 47 | mem_block *head; 48 | mem_block *tail; 49 | mem_node *nhead; 50 | unsigned total; 51 | unsigned left; 52 | unsigned block_size; 53 | private: 54 | int add_block(int num); 55 | public: 56 | void destory() 57 | { 58 | mem_block *next,*cur; 59 | cur = this->head; 60 | next = NULL; 61 | while(cur != NULL) 62 | { 63 | next = cur->next; 64 | free(cur->head); 65 | free(cur); 66 | cur = next; 67 | } 68 | this->head = this->tail = NULL; 69 | this->nhead = NULL; 70 | this->total = this->left = this->block_size = 0; 71 | } 72 | static fixmemorypool *getInstance() 73 | { 74 | if(fixmemorypool::Instance == NULL) 75 | { 76 | fixmemorypool::Instance = new fixmemorypool; 77 | } 78 | return fixmemorypool::Instance; 79 | } 80 | public: 81 | type *mem_pool_alloc(); 82 | void mem_pool_release(type *ret); 83 | ~ fixmemorypool() 84 | { 85 | this->destory(); 86 | } 87 | 88 | }; 89 | 90 | template 91 | fixmemorypool* fixmemorypool::Instance = NULL; 92 | 93 | template 94 | typename fixmemorypool::release fixmemorypool::rel; 95 | 96 | template 97 | int fixmemorypool::add_block(int num) 98 | { 99 | mem_block *btemp = new mem_block; 100 | if((btemp->head = (mem_node *)malloc(sizeof(mem_node) * num)) == NULL) 101 | { 102 | return 0; 103 | } 104 | btemp->tail = btemp->head + this->block_size - 1; 105 | mem_node *p; 106 | for(p = btemp->head;p < btemp->tail;++ p) 107 | { 108 | p->next = (p + 1); 109 | } 110 | p->next = NULL; 111 | 112 | btemp->next = this->head; 113 | this->head = btemp; 114 | this->nhead = btemp->head; 115 | if(this->tail == NULL) 116 | { 117 | this->tail = btemp; 118 | } 119 | this->total += num; 120 | this->left += num; 121 | return 1; 122 | } 123 | 124 | template 125 | type *fixmemorypool::mem_pool_alloc() 126 | { 127 | if(this->nhead == NULL) 128 | { 129 | if(!this->add_block(this->block_size)) 130 | { 131 | return 0; 132 | } 133 | } 134 | mem_node *p = this->nhead; 135 | this->nhead = p->next; 136 | -- this->left; 137 | //printf("alloc:%d,%d\n",this->total,this->left); 138 | return &p->node; 139 | } 140 | 141 | template 142 | void fixmemorypool::mem_pool_release(type *ret) 143 | { 144 | if(ret == NULL) 145 | { 146 | return; 147 | } 148 | ((mem_node *)ret)->next = this->nhead; 149 | this->nhead = (mem_node *)ret; 150 | ++ this->left; 151 | //printf("release:%d,%d\n",this->total,this->left); 152 | } 153 | 154 | #endif /* FIXMEMORYPOOL_H_ */ 155 | -------------------------------------------------------------------------------- /src/deviceProcess.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * deviceProcess.cpp 3 | * 4 | * Created on: Mar 27, 2013 5 | * Author: keym 6 | */ 7 | 8 | #include"deviceProcess.h" 9 | #include"commondata/magicNum.h" 10 | #include"messagehandle/messageHandle.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | deviceProcess *deviceProcess::_singleInstance = NULL; 22 | static void packSendAlarmMsg(void *buffer); 23 | 24 | void deviceProcess::initializeListenfd() 25 | { 26 | handleEpollSocket::initializeEpoll(); 27 | 28 | if((this->_netListenfd = socket(AF_INET,SOCK_STREAM,0)) < 0) 29 | { 30 | std::cerr<<"parentProcess::initializeListenfdAndEpollfd:socket"<_netListenfd,(struct sockaddr*)&addr,sizeof(addr))<0) 39 | { 40 | perror("bind:"); 41 | std::cerr<<"parentProcess::initializeListenfdAndEpollfd:bind"<_netListenfd,magicnum::parentprocess::LISTNEPORT) == magicnum::FAILIED) 45 | { 46 | std::cerr<<"parentProcess::initializeListenfdAndEpollfd:ListenAndSetBlockNum"<_netListenfd); 50 | } 51 | 52 | int deviceProcess::GetSocketfdAndRun() 53 | { 54 | pid_t pid; 55 | int sockfd[2]; 56 | socketpair(AF_LOCAL,SOCK_STREAM,0,sockfd); 57 | if((pid = fork()) > 0) 58 | { 59 | close(sockfd[1]); 60 | return sockfd[0]; 61 | } 62 | //client 63 | close(sockfd[0]); 64 | handleEpollSocket::addEpollSocket(sockfd[1]); 65 | this->_parentfd = sockfd[1]; 66 | this->CommunicationHandle(); 67 | assert(1 == 0); 68 | std::cerr<<"processManage::createSingleProcess:assert"<_maxNumOfEpollfd + 1]; 76 | std::deque _dPid; 77 | int connfd; 78 | std::deque newcondeque; 79 | for(;;) 80 | { 81 | int nfds; 82 | if((nfds=epoll_wait(_epfd,events,this->_maxNumOfEpollfd,magicnum::parentprocess::EPOLLTIMEOUT)) <= 0) 83 | { 84 | if (errno != EINTR) 85 | { 86 | std::cerr<<"parentProcess::CommunicationHandle:epoll_wait"<_netListenfd) 95 | { 96 | struct sockaddr_in clientaddr; 97 | socklen_t clilen = sizeof(clientaddr); 98 | if((connfd=accept(this->_netListenfd,(struct sockaddr*)&clientaddr,&clilen))<0) 99 | { 100 | if(errno == EINTR){continue;} 101 | std::cerr<<"parentProcess::CommunicationHandle:accept"<msgHandle(readbuf,connfd,this); 107 | } 108 | else if(events[i].events&EPOLLOUT) 109 | { 110 | //通知的顺序与投递的顺序相同 111 | handleEpollSocket::sendData(events[i].data.fd); 112 | handleEpollSocket::modEpollSocket(events[i].data.fd,false); 113 | } 114 | else if((events[i].events&EPOLLHUP)||(events[i].events&EPOLLERR)) 115 | { 116 | std::cerr<<"parentProcess::CommunicationHandle:accept"<_type = magicnum::messagetype::NULLSENDALA; 127 | _head->_size = 0; 128 | } 129 | -------------------------------------------------------------------------------- /src/mempool/mempool.cpp: -------------------------------------------------------------------------------- 1 | #include"mempool/mempool.h" 2 | #include 3 | 4 | #include 5 | 6 | #define ALIGN 8 7 | 8 | MemPool* MemPool::_instance = NULL; 9 | 10 | static size_t check_align_addr(void*& pBuf) 11 | { 12 | size_t align = 0; 13 | size_t addr = (size_t)pBuf; 14 | align = (ALIGN - addr % ALIGN) % ALIGN; 15 | pBuf = (char*)pBuf + align; 16 | return align; 17 | } 18 | 19 | 20 | static size_t check_align_block(size_t size) 21 | { 22 | size_t align = size % UNITSIZE; 23 | 24 | return size - align; 25 | } 26 | 27 | static size_t check_align_size(size_t size) 28 | { 29 | size = (size + UNITSIZE - 1) / UNITSIZE * UNITSIZE; 30 | return size; 31 | } 32 | 33 | MemPool::MemPool(void *mem,int size) 34 | { 35 | assert(mem != NULL); 36 | this->pbuf = mem; 37 | this->isize = size; 38 | 39 | this->iunitcount = (this->isize + UNITSIZE - 1) / UNITSIZE; 40 | this->punit = (MemUnit*)this->pbuf; 41 | 42 | this->blockpool.createList((MemBlock*)(this->punit + this->iunitcount),this->iunitcount); 43 | 44 | this->pmem = (char*)this->pbuf + this->iunitcount * (sizeof(MemUnit) + sizeof(MemBlock)); 45 | 46 | size_t align = check_align_addr(this->pmem); 47 | this->itotalsize = this->isize - align - this->iunitcount * (sizeof(MemUnit) + sizeof(MemBlock)); 48 | this->itotalsize = check_align_block(this->itotalsize); 49 | this->imemcount = this->itotalsize / UNITSIZE; 50 | 51 | MemBlock *temp = this->blockpool.popFront(); 52 | temp->pUnit = this->punit; 53 | this->freeblock.pushFront(temp); 54 | 55 | this->punit[0].icount = this->imemcount; 56 | this->punit[0].pBlock = temp; 57 | this->punit[this->imemcount - 1].istart = 0; 58 | 59 | this->iusedsize = 0; 60 | } 61 | 62 | static void* index2addr(void* pmem, size_t index) 63 | { 64 | void* ret = (void*)((char*)pmem + index *UNITSIZE); 65 | return ret; 66 | } 67 | 68 | static size_t addr2index(void* pmem, void* addr) 69 | { 70 | size_t index = ((char*)addr - (char*)pmem) / UNITSIZE; 71 | return index; 72 | } 73 | 74 | void *MemPool::getMem(size_t size) 75 | { 76 | size_t memsize = check_align_size(size); 77 | MemBlock *temp = this->freeblock.getBlock(memsize); 78 | if(temp == NULL) 79 | { 80 | perror("can not alloc"); 81 | return NULL; 82 | } 83 | 84 | this->iusedsize += memsize; 85 | //������ 86 | if(temp->pUnit->icount * UNITSIZE == memsize) 87 | { 88 | size_t index = temp->pUnit - this->punit; 89 | this->freeblock.deleteBlock(temp); 90 | this->blockpool.pushFront(temp); 91 | return index2addr(this->pmem,index); 92 | } 93 | else 94 | { 95 | MemUnit *allocunit = temp->pUnit; 96 | size_t origcount = allocunit->icount; 97 | 98 | size_t allocindex = allocunit - this->punit; 99 | allocunit->icount = memsize / UNITSIZE; 100 | //printf("allocindex:%d,icount:%d\n",allocindex,allocunit->icount); 101 | allocunit->pBlock = NULL;//�����������Ϊ�� 102 | this->punit[allocindex + allocunit->icount - 1].istart = allocindex; 103 | 104 | this->punit[allocindex + allocunit->icount].icount = origcount - allocunit->icount; 105 | this->punit[allocindex + allocunit->icount].pBlock = temp; 106 | this->punit[allocindex + origcount - 1].istart = allocindex + allocunit->icount; 107 | temp->pUnit = &this->punit[allocindex + allocunit->icount]; 108 | 109 | return index2addr(this->pmem,allocindex); 110 | } 111 | } 112 | 113 | void MemPool::freeMem(void *mem) 114 | { 115 | size_t index = addr2index(this->pmem,mem); 116 | size_t startindex = this->punit[index - 1].istart; 117 | MemUnit *cur = &this->punit[index]; 118 | MemUnit *pre = NULL; 119 | MemUnit *next = NULL; 120 | 121 | this->iusedsize -= cur->icount * UNITSIZE; 122 | //���ǵ�һ�� 123 | if(index != 0) 124 | { 125 | pre = &this->punit[startindex]; 126 | } 127 | //�������һ�� 128 | if(index + cur->icount != this->imemcount) 129 | { 130 | next = &this->punit[index + cur->icount]; 131 | } 132 | //ǰ���ǿհף��ϲ� 133 | if(pre != NULL && next != NULL && pre->pBlock != NULL && next->pBlock != NULL) 134 | { 135 | this->punit[index + cur->icount + next->icount - 1].istart = startindex; 136 | pre->icount += cur->icount + next->icount; 137 | this->freeblock.deleteBlock(next->pBlock); 138 | this->blockpool.pushFront(next->pBlock); 139 | cur->pBlock = next->pBlock = NULL; 140 | } 141 | //ǰ��հף���ǰ��ϲ� 142 | else if(pre != NULL && pre->pBlock != NULL) 143 | { 144 | this->punit[index + cur->icount - 1].istart = startindex; 145 | pre->icount += cur->icount; 146 | cur->pBlock = NULL; 147 | } 148 | //����հף��ͺ���ϲ� 149 | else if(next != NULL && next->pBlock != NULL) 150 | { 151 | next->pBlock->pUnit = cur; 152 | this->punit[index + cur->icount + next->icount - 1].istart = index; 153 | cur->icount += next->icount; 154 | cur->pBlock = next->pBlock; 155 | next->pBlock = NULL; 156 | } 157 | //ǰ�󶼲��ɺϲ� 158 | else 159 | { 160 | MemBlock *newblock = this->blockpool.popFront(); 161 | newblock->pUnit = cur; 162 | cur->pBlock = newblock; 163 | this->freeblock.pushFront(newblock); 164 | } 165 | } 166 | 167 | -------------------------------------------------------------------------------- /src/parentProcess.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * parentProcess.cpp 3 | * 4 | * Created on: 2013-1-25 5 | * Author: keym 6 | */ 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include"parentProcess.h" 18 | #include"processManage.h" 19 | #include"deviceProcess.h" 20 | 21 | #include"messagehandle/messageHandle.h" 22 | 23 | void parentProcess::initializeListenfd() 24 | { 25 | if((this->_netListenfd = socket(AF_INET,SOCK_STREAM,0)) < 0) 26 | { 27 | std::cerr<<"parentProcess::initializeListenfdAndEpollfd:socket"<_netListenfd,(struct sockaddr*)&addr,sizeof(addr))<0) 36 | { 37 | perror("bind:"); 38 | std::cerr<<"parentProcess::initializeListenfdAndEpollfd:bind"<_netListenfd,magicnum::parentprocess::LISTNEPORT) == magicnum::FAILIED) 42 | { 43 | std::cerr<<"parentProcess::initializeListenfdAndEpollfd:ListenAndSetBlockNum"<_netListenfd); 47 | } 48 | 49 | void parentProcess::initializeChildProcessfd(int num) 50 | { 51 | processManage::GetInstance()->CreateAllProcess(num,this); 52 | this->_devicefd = deviceProcess::GetInstance()->GetSocketfdAndRun(); 53 | handleEpollSocket::addEpollSocket(this->_devicefd); 54 | } 55 | 56 | void parentProcess::InitializeManage(int num) 57 | throw(std::exception) 58 | { 59 | handleEpollSocket::initializeEpoll(); 60 | this->initializeListenfd(); 61 | this->initializeChildProcessfd(num); 62 | } 63 | 64 | void parentProcess::acceptNewConnection(int newfd) 65 | { 66 | int _allocatefd = processManage::GetInstance()->OccupyProcessToClient(this); 67 | if(_allocatefd == magicnum::FAILIED){return;} 68 | this->_dnewConnectSocket.push_back(newfd); 69 | commontype::headInfo _head; 70 | _head._type = magicnum::messagetype::NULLSENDFDT; 71 | _head._size = 0; 72 | messageHandle::getInstance()->msgHandle(&_head,_allocatefd,this); 73 | } 74 | 75 | void parentProcess::sendNewConnection(int sendfd) 76 | { 77 | assert(this->_dnewConnectSocket.size() != 0); 78 | int newfd = this->_dnewConnectSocket[0]; 79 | this->_dnewConnectSocket.pop_front(); 80 | if(send_fd(sendfd,newfd) == magicnum::SUCCESS) 81 | { 82 | this->_cfdAndAlloc.AddFreeSockfd(sendfd); 83 | } 84 | close(newfd); 85 | } 86 | 87 | void parentProcess::AddSocketToEpoll(int socket) 88 | { 89 | handleEpollSocket::addEpollSocket(socket); 90 | } 91 | 92 | void parentProcess::relEpollSocket(int socket,PROCESSSTATE type) 93 | { 94 | int result = processManage::GetInstance()->ReleaseProcess(socket,type); 95 | this->_cfdAndAlloc.DelCloseSockfd(socket); 96 | if(type == ERR && result == magicnum::SUCCESS) 97 | { 98 | printf("relEpollSocket error\n"); 99 | delEpollSocket(socket); 100 | } 101 | } 102 | 103 | void parentProcess::CommunicationHandle() 104 | { 105 | struct epoll_event events[this->_maxNumOfEpollfd + 1]; 106 | std::deque _dPid; 107 | int connfd; 108 | int readbytes; 109 | char readbuf[magicnum::MSGHEADSIZE]; 110 | std::deque newcondeque; 111 | for(;;) 112 | { 113 | int nfds; 114 | if((nfds=epoll_wait(_epfd,events,this->_maxNumOfEpollfd,magicnum::parentprocess::EPOLLTIMEOUT)) <= 0) 115 | { 116 | if (errno != EINTR) 117 | { 118 | std::cerr<<"parentProcess::CommunicationHandle:epoll_wait"<_netListenfd) 127 | { 128 | struct sockaddr_in clientaddr; 129 | socklen_t clilen = sizeof(clientaddr); 130 | if((connfd=accept(this->_netListenfd,(struct sockaddr*)&clientaddr,&clilen))<0) 131 | { 132 | if(errno == EINTR){continue;} 133 | std::cerr<<"parentProcess::CommunicationHandle:accept"<acceptNewConnection(connfd); 137 | continue; 138 | } 139 | else if(events[i].events&EPOLLIN) 140 | { 141 | memset(readbuf,0,magicnum::MSGHEADSIZE); 142 | int _childSocketfd = events[i].data.fd; 143 | if((readbytes=RepeatRecv(_childSocketfd,readbuf,sizeof(commontype::headInfo))) == magicnum::FAILIED) 144 | { 145 | this->relEpollSocket(_childSocketfd,ERR); 146 | continue; 147 | } 148 | messageHandle::getInstance()->msgHandle(readbuf,_childSocketfd,this); 149 | } 150 | else if(events[i].events&EPOLLOUT) 151 | { 152 | //通知的顺序与投递的顺序相同 153 | handleEpollSocket::sendData(events[i].data.fd); 154 | if(this->_dnewConnectSocket.size() != 0) 155 | { 156 | this->sendNewConnection(events[i].data.fd); 157 | } 158 | handleEpollSocket::modEpollSocket(events[i].data.fd,false); 159 | } 160 | else if((events[i].events&EPOLLHUP)||(events[i].events&EPOLLERR)) 161 | { 162 | this->relEpollSocket(events[i].data.fd,ERR); 163 | } 164 | } 165 | } 166 | 167 | } 168 | -------------------------------------------------------------------------------- /src/processManage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * processManage.cpp 3 | * 4 | * Created on: 2013-1-24 5 | * Author: keym 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include"processManage.h" 14 | #include"commonfunction/localSocketFun.h" 15 | #include"commonfunction/netSocketFun.h" 16 | 17 | #include"childProcess.h" 18 | #include"parentProcess.h" 19 | #include 20 | 21 | processManage* processManage::_singleInstance = NULL; 22 | 23 | void processManage::getSystemLimit() 24 | { 25 | rlimit limit; 26 | getrlimit(RLIMIT_NPROC,&limit); 27 | if(limit.rlim_cur > magicnum::processmanage::MAXNUMPROCESS) 28 | { 29 | this->_uMaxNumOfProcess = limit.rlim_cur; 30 | } 31 | } 32 | 33 | void processManage::releaseAllData() 34 | { 35 | vectorIterType iter = this->_vProcessInfo.begin(); 36 | while(iter != this->_vProcessInfo.end()) 37 | { 38 | if((*iter) != NULL) 39 | { 40 | delete (*iter); 41 | } 42 | ++ iter; 43 | } 44 | this->_vProcessInfo.clear(); 45 | this->_mProcessSocketAndIndex.clear(); 46 | } 47 | 48 | void processManage::createSingleProcess() 49 | { 50 | pid_t pid; 51 | int sockfd[2]; 52 | socketpair(AF_LOCAL,SOCK_STREAM,0,sockfd); 53 | if((pid = fork()) > 0) 54 | { 55 | childProcessInfo *c = new childProcessInfo(sockfd[0],INIT,pid); 56 | std::cout<<"new pid:"<_uTotalNumOfProcess<_vProcessInfo.push_back(c); 59 | return; 60 | } 61 | //client 62 | close(sockfd[0]); 63 | childProcess p(sockfd[1]); 64 | p.InitializeProcess(); 65 | p.CommunicateHandle(); 66 | assert(1 == 0); 67 | std::cerr<<"processManage::createSingleProcess:assert"<_uMinNumOfProcess || num > this->_uMaxNumOfProcess){throw std::exception();} 75 | 76 | unsigned i; 77 | this->_uTotalNumOfProcess += num; 78 | 79 | unsigned _totalnum = this->_vProcessInfo.size(); 80 | for(i = 0;i < num;++ i) 81 | { 82 | this->createSingleProcess(); 83 | unsigned index = _totalnum + i; 84 | int socket = this->_vProcessInfo[index]->GetProcessSocket(); 85 | pobject->AddSocketToEpoll(socket); 86 | this->_mProcessSocketAndIndex[socket] = index; 87 | } 88 | } 89 | 90 | int processManage::OccupyProcessToClient(parentProcess *pobject) 91 | { 92 | if(this->_uNumOfRunningProcess == this->_uMaxNumOfProcess) 93 | { 94 | return magicnum::FAILIED; 95 | } 96 | 97 | if(this->_uNumOfRunningProcess == this->_uTotalNumOfProcess) 98 | { 99 | this->CreateAllProcess(this->_uTotalNumOfProcess,pobject); 100 | } 101 | 102 | vectorIterType viter = this->_vProcessInfo.begin(); 103 | while(viter != this->_vProcessInfo.end()) 104 | { 105 | if((*viter)->GetProcessState() == INIT) 106 | { 107 | break; 108 | } 109 | ++ viter; 110 | } 111 | 112 | assert(viter != this->_vProcessInfo.end()); 113 | 114 | (*viter)->SetProcessState(BUSY); 115 | ++ this->_uNumOfRunningProcess; 116 | std::cout<<"occupy:"<<(*viter)->GetProcessPid()<GetProcessSocket(); 118 | } 119 | 120 | void processManage::moveErrorProcessToTail() 121 | { 122 | vectorIterType reverseOrderIter = this->_vProcessInfo.end(); 123 | vectorIterType forwardOrderIter = this->_vProcessInfo.begin(); 124 | 125 | while(forwardOrderIter < reverseOrderIter) 126 | { 127 | if((*forwardOrderIter)->GetProcessState() == ERR) 128 | { 129 | -- reverseOrderIter; 130 | while((*reverseOrderIter)->GetProcessState() == ERR) 131 | { 132 | -- reverseOrderIter; 133 | } 134 | childProcessInfo *temp = (*reverseOrderIter); 135 | (*reverseOrderIter) = (*forwardOrderIter); 136 | (*forwardOrderIter) = temp; 137 | } 138 | ++ forwardOrderIter; 139 | } 140 | } 141 | 142 | int processManage::ReleaseProcess(int socket,PROCESSSTATE type) 143 | { 144 | std::map::iterator iter = this->_mProcessSocketAndIndex.find(socket); 145 | 146 | if(iter == this->_mProcessSocketAndIndex.end()) 147 | { 148 | return magicnum::FAILIED; 149 | } 150 | 151 | this->_vProcessInfo[iter->second]->SetProcessState(type); 152 | -- this->_uNumOfRunningProcess; 153 | std::cout<<"release:"<_vProcessInfo[iter->second]->GetProcessPid()<<","<_uNumOfRunningProcess == this->_uTotalNumOfProcess / magicnum::processmanage::DIVISOR) 155 | { 156 | if(this->_uTotalNumOfProcess == this->_uMinNumOfProcess) 157 | { 158 | return magicnum::SUCCESS; 159 | } 160 | this->moveErrorProcessToTail(); 161 | 162 | vectorIterType forwardOrderIter = this->_vProcessInfo.begin(); 163 | vectorIterType reverseOrderIter = this->_vProcessInfo.begin() + this->_vProcessInfo.size() / 2; 164 | 165 | this->_mProcessSocketAndIndex.clear(); 166 | 167 | while(reverseOrderIter != this->_vProcessInfo.end()) 168 | { 169 | if((*reverseOrderIter)->GetProcessState() == BUSY) 170 | { 171 | while((*forwardOrderIter)->GetProcessState() == BUSY) 172 | { 173 | ++ forwardOrderIter; 174 | } 175 | childProcessInfo *temp = (*reverseOrderIter); 176 | (*reverseOrderIter) = (*forwardOrderIter); 177 | (*forwardOrderIter) = temp; 178 | } 179 | if((*reverseOrderIter)->GetProcessState() == INIT) 180 | { 181 | close((*reverseOrderIter)->GetProcessSocket()); 182 | std::cerr<<"child-init:"<<(*reverseOrderIter)->GetProcessPid()<GetProcessPid(),SIGTERM); 184 | } 185 | else 186 | { 187 | std::cerr<<"child-error:"<<(*reverseOrderIter)->GetProcessPid()<_vProcessInfo.erase(this->_vProcessInfo.begin() + this->_vProcessInfo.size() / 2,this->_vProcessInfo.end()); 194 | unsigned i; 195 | for(i = 0;i < this->_vProcessInfo.size();++ i) 196 | { 197 | this->_mProcessSocketAndIndex[this->_vProcessInfo[i]->GetProcessSocket()] = i; 198 | } 199 | this->_uTotalNumOfProcess /= 2; 200 | } 201 | std::cout<<"total,runing:"<_uTotalNumOfProcess<<","<_uNumOfRunningProcess< 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 37 | 38 | 39 | 40 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 614 | 615 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 922 | 923 | 924 | 925 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | 982 | 983 | 984 | 985 | 986 | 987 | 988 | 989 | 990 | 991 | 992 | 993 | 994 | 995 | 996 | 997 | 998 | 999 | 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | 1062 | 1063 | 1064 | 1065 | 1066 | 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | 1083 | 1084 | 1085 | 1086 | 1087 | 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | 1096 | 1097 | 1098 | 1099 | 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | 1138 | 1139 | 1140 | 1141 | 1142 | 1143 | 1144 | 1145 | 1146 | 1147 | 1148 | 1149 | 1150 | 1151 | 1152 | 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | 1162 | 1163 | --------------------------------------------------------------------------------