cdrserver.cpp
来自「MySQL数据库开发源码 值得一看哦」· C++ 代码 · 共 1,492 行 · 第 1/5 页
CPP
1,492 行
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//* **************************************************************** *//* *//* S E R V . T C P *//* * This is an example program that demonstrates the use of *//* stream sockets as an IPC mechanism. This contains the server, *//* and is intended to operate in conjunction with the client *//* program found in client.tcp. Together, these two programs *//* demonstrate many of the features of sockets, as well as good *//* conventions for using these features. *//* * This program provides a service called "example". In order for*//* it to function, an entry for it needs to exist in the *//* ./etc/services file. The port address for this service can be *//* any port number that is likely to be unused, such as 22375, *//* for example. The host on which the client will be running *//* must also have the same entry (same port number) in its *//* ./etc/services file. *//* **************************************************************** */#include <ndb_global.h>/******** NDB INCLUDE ******/#include <NdbApi.hpp>/***************************//*#include <sys/shm.h>*/#include <pthread.h>#include <sys/sem.h>#include <sys/shm.h>#include <netinet/in.h>#include <signal.h>#include <netdb.h>#include <time.h>#include <synch.h>#include <sched.h>extern "C" {#include "utv.h"#include "vcdrfunc.h"#include "bcd.h"}#ifndef TESTLEV#define TESTLEV#endif//#define DEBUG//#define MYDEBUG//#define SETDBG//#define ops_before_exe 64#define MAXOPSEXEC 1024/* Used in nanosleep *//**** NDB ********/static int bTestPassed;void create_table(Ndb* pMyNdb);void error_handler(const char* errorText);/*****************/static struct timespec tmspec1;static int server(long int);/* Function for initiating the cdr-area and make it clean for ongoing calls */static int s; /* connected socket descriptor */static int ls; /* listen socket descriptor */static struct hostent *hp; /* pointer to host info for remote host */static struct servent *sp; /* pointer to service information */struct linger linger; /* allow a lingering, graceful close; */ /* used when setting SO_LINGER */static struct sockaddr_in myaddr_in; /* for local socket address */static struct sockaddr_in peeraddr_in; /* for peer socket address */static FILE *fi; /* Log output */static char temp[600]="";static int ops_before_exe = 1; /* Number of operations per execute, default is 1, but it can be changed with the -o parameter. *//*---------------------------------------------------------------------- M A I N * This routine starts the server. It forks, leaving the child to do all the work, so it does not have to be run in the background. It sets up the listen socket, and for each incoming connection, it forks a child process to process the data. It will loop forever, until killed by a signal. ----------------------------------------------------------------------*//****** NDB *******/static char *tableName = "VWTABLE";/******************/#include <iostream>using namespace std;int main(int argc, const char** argv){ ndb_init(); /******** NDB ***********/ /* Ndb MyNdb( "TEST_DB" ); int tTableId; */ /************************/ char tmpbuf[400]; /* Loop and status variables */ int i,j,found; /* Used by the server */ int addrlen; /* return code used with functions */ int rc; i = 1; while (argc > 1) { if (strcmp(argv[i], "-o") == 0) { ops_before_exe = atoi(argv[i+1]); if ((ops_before_exe < 1) || (ops_before_exe > MAXOPSEXEC)) { cout << "Number of operations per execute must be at least 1, and at most " << MAXOPSEXEC << endl; exit(1); } } else { cout << "Invalid parameter!" << endl << "Look in cdrserver.C for more info." << endl; exit(1); } argc -= 2; i = i + 2; } /* Setup log handling */ logname(temp,"Cdrserver","Mother",""); puts(temp); fi=fopen(temp,"w"); if (fi == NULL) { perror(argv[0]); exit(EXIT_FAILURE); } m2log(fi,"Initiation of program"); /***** NDB ******/ /* MyNdb.init(); if (MyNdb.waitUntilReady(30) != 0) { puts("Not ready"); exit(-1); } tTableId = MyNdb.getTable()->openTable(tableName); if (tTableId == -1) { printf("%d: Creating table",getpid()); create_table(&MyNdb); } else printf("%d: Table already create",getpid()); */ /****************/ /* clear out address structures */ memset ((char *)&myaddr_in, 0, sizeof(struct sockaddr_in)); memset ((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in)); m2log(fi,"Socket setup starting"); /* Set up address structure for the listen socket. */ myaddr_in.sin_family = AF_INET; /* The server should listen on the wildcard address, */ /* rather than its own internet address. This is */ /* generally good practice for servers, because on */ /* systems which are connected to more than one */ /* network at once will be able to have one server */ /* listening on all networks at once. Even when the */ /* host is connected to only one network, this is good */ /* practice, because it makes the server program more */ /* portable. */ myaddr_in.sin_addr.s_addr = INADDR_ANY; /* Find the information for the "cdrserver" server */ /* in order to get the needed port number. */ sp = getservbyname ("cdrserver", "tcp"); if (sp == NULL) { m2log(fi,"Service cdrserver not found in /etc/services"); m2log(fi,"Terminating."); exit(EXIT_FAILURE); } myaddr_in.sin_port = sp->s_port; /* Create the listen socket.i */ ls = socket (AF_INET, SOCK_STREAM, 0); if (ls == -1) { m2log(fi,"Unable to create socket"); m2log(fi,"Terminating."); exit(EXIT_FAILURE); } printf("Socket created\n"); printf("Wait..........\n"); /* Bind the listen address to the socket. */ if (bind(ls,(struct sockaddr*)&myaddr_in, sizeof(struct sockaddr_in)) == -1) { m2log(fi,"Unable to bind address"); m2log(fi,"Terminating."); exit(EXIT_FAILURE); } /* Initiate the listen on the socket so remote users */ /* can connect. The listen backlog is set to 5, which */ /* is the largest currently supported. */ if (listen(ls, 5) == -1) { m2log(fi,"Unable to listen on socket"); m2log(fi,"Terminating."); exit(EXIT_FAILURE); } /* Now, all the initialization of the server is */ /* complete, and any user errors will have already */ /* been detected. Now we can fork the daemon and */ /* return to the user. We need to do a setpgrp */ /* so that the daemon will no longer be associated */ /* with the user's control terminal. This is done */ /* before the fork, so that the child will not be */ /* a process group leader. Otherwise, if the child */ /* were to open a terminal, it would become associated */ /* with that terminal as its control terminal. It is */ /* always best for the parent to do the setpgrp. */ m2log(fi,"Socket setup completed"); m2log(fi,"Start server"); setpgrp(); /* Initiate the tmspec struct for use with nanosleep() */ tmspec1.tv_sec = 0; tmspec1.tv_nsec = 1; printf("Waiting for client to connect.........\n"); printf("Done\n"); switch (fork()) { case -1: /* Unable to fork, for some reason. */ m2log(fi,"Failed to start server"); m2log(fi,"Terminating."); fclose(fi); perror(argv[0]); fprintf(stderr, "%s: unable to fork daemon\n", argv[0]); exit(EXIT_FAILURE); break; case 0: /* The child process (daemon) comes here. */ m2log(fi,"Server started"); /* Close stdin and stderr so that they will not */ /* be kept open. Stdout is assumed to have been */ /* redirected to some logging file, or /dev/null. */ /* From now on, the daemon will not report any */ /* error messages. This daemon will loop forever, */ /* waiting for connections and forking a child */ /* server to handle each one. */ close((int)stdin); close((int)stderr); /* Set SIGCLD to SIG_IGN, in order to prevent */ /* the accumulation of zombies as each child */ /* terminates. This means the daemon does not */ /* have to make wait calls to clean them up. */ signal(SIGCLD, SIG_IGN); for(EVER) { if ((checkchangelog(fi,temp))==0)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?