⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcp_server.c

📁 用GTK+做用户界面 股票每日分时行情用数据库管理——MYSQL 软件应用方式客户端/服务器模式 基于TCP/IP的C/S通信模式 实现STOCK
💻 C
字号:
#include "tcp_server.h"#include "config.h"#include <fstream.h>#include <iostream.h>#ifdef DEFINE_SOCKLEN_T typedef unsigned int socklen_t ;#endifstatic int glob_sock_fd = -1;static void reaper(int sig_num);  // this one has to be outside of classstatic void do_cleanup(int sig_num);static void do_cleanup(int sig_num);static void do_cleanup(int ) {   if(glob_sock_fd >= 0)     close(glob_sock_fd);   exit(0); }static void reaper(int) {   int   status;    while (waitpid(-1, &status, WNOHANG) > 0)       signal(SIGCHLD, reaper); }void TcpServer::start_server(int port, int listen_queue_size, char* log_file) {  if(!log_file)   log = stderr;  else if(!strcmp("-", log_file))    log = stderr;  else   {    log = fopen(log_file, "a");    if(!log)     {      fprintf(stderr, "Tcp Server: could not open log file %s : %s\n",         log_file, strerror(errno));      exit(1);     }   }    setbuf(log, NULL);  struct protoent *tcp_prot = getprotobyname("tcp");  if(!tcp_prot)   fatal_error("TcpServer: tcp does not seem to be supported");  socket_fd = socket(AF_INET,SOCK_STREAM, tcp_prot->p_proto);  if(socket_fd == -1)   fatal_error("TcpServer: error creating the socket: %s", strerror(errno));    glob_sock_fd = socket_fd; // this is for the signal handlers  int one = 1;  if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(int)) < 0)    fatal_error("TcpServer: failed on setsockopt(): %s", strerror(errno));  memset(&serv_addr, 0, sizeof(serv_addr));  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  serv_addr.sin_port = htons(port);  serv_addr.sin_family = AF_INET;     if(bind(socket_fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr))                         == -1)    {     fatal_error("TcpServer: Could not bind: %s", strerror(errno));    }   if(listen(socket_fd, listen_queue_size) == -1)    fatal_error("TcpServer: could not listen: %s", strerror(errno));   signal(SIGTERM, do_cleanup); }void TcpServer::run_server() {       pid_t fork_pid = fork();   if(fork_pid == -1)    fatal_error("TcpServer: could not fork into background: %s", strerror(errno));    signal(SIGCHLD, reaper);   if(fork_pid > 0)     {     close(socket_fd);     return;    }   close(0);   close(1);   close(2);   socklen_t serv_addr_size = sizeof(serv_addr);   while(1)    {     int client_socket_fd = accept(socket_fd, (struct sockaddr*)&serv_addr, &serv_addr_size);          if(client_socket_fd == -1)      {       if(errno != EINTR)        warn( "TcpServer: error on accept : %s\n", strerror(errno));      }     else      {       int client_fork_pid = fork();       if(client_fork_pid == -1)        warn("TcpServer: could not fork off a client handler : %s\n",	 strerror(errno));       else        if(client_fork_pid == 0)	 {	  close(socket_fd);		  if(access_control)	   if(!access_allowed(client_socket_fd))	    {	     close(client_socket_fd);	     return;	    }	  handle_client(client_socket_fd);	  close(client_socket_fd); 	  return;	 }	else	 close(client_socket_fd);      }    } }   TcpServer::TcpServer(int port,int listen_queue_size, char* log_file):  debug_level(0), access_control(0) {  start_server(port, listen_queue_size, log_file); }TcpServer::~TcpServer() { }int TcpServer::access_allowed(int client_socket_fd) {  struct sockaddr_in peername;  socklen_t peername_len = sizeof(sockaddr_in);  if(getpeername(client_socket_fd, (struct sockaddr*)&peername, &peername_len) == -1)   {    warn("Cannot get peer - access denied");    return 0;   }  else   {    if(ip_rules.ok(peername.sin_addr))     return 1;    char* src_addr = inet_ntoa(peername.sin_addr);    log_access_denied(src_addr);   }   return 0; }char* TcpServer::get_peer_addr(int client_socket_fd) {  struct sockaddr_in peername;  socklen_t peername_len = sizeof(sockaddr_in);  if(getpeername(client_socket_fd, (struct sockaddr*)&peername, &peername_len) == -1)   warn("Cannot get peer");  else   {    char* src_addr = inet_ntoa(peername.sin_addr);    return src_addr;   }  return "unknown"; }void TcpServer::cleanup() {  if(socket_fd >= 0)   close(socket_fd); }#ifdef DEBUGclass TestServer: public TcpServer {  protected:    void handle_client(int client_socket_fd);  public:   TestServer(int port, int queue_size, char* log_file) :      TcpServer(port, queue_size, log_file)    {    }    };void TestServer::handle_client(int client_socket_fd) {  char buf[512];  info("connect from %s ", get_peer_addr(client_socket_fd));  FILE *in  = fdopen(client_socket_fd, "r");  FILE *out  = fdopen(client_socket_fd, "w");  setbuf(in, NULL);  setbuf(out, NULL);  if(!in)   {    warn("fdopen failed on 'in': %s\n", strerror(errno));    return;   }  if(!out)   {    warn("fdopen failed on 'out': %s\n", strerror(errno));    return;   }  fprintf(out, "Please enter your name:");  fgets( buf, sizeof(buf), in);  fprintf(out, "Good-bye, %s\n", buf); }int main(int c, char** argv) {  int port = 1234;  char* log_file = "-";  char* ip_rules_file = NULL;  if(c > 1) port = atoi(argv[1]);  if(c > 2) log_file = argv[2];  if(c > 3) ip_rules_file = argv[3];     TestServer s(port, 50, log_file);   if(ip_rules_file)   {    ifstream rules(ip_rules_file);    if(!rules)    {     cerr << "Could not open rules file" << endl;     exit(1);    }         while(1)    {     char netnum[128], netmask[128];     rules >> netnum >> netmask;     cout << "reading: " << netnum << " " << netmask << endl;     if(!rules) break;     s.add_ip_rule(netnum, netmask);    }    s.enable_access_control();   }       s.run_server(); }#endif 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -