zoukankan      html  css  js  c++  java
  • 实现最简单的网络服务器[作业]

    要求:

    1.客户端与服务端可以通过TCP通信;

    2.处理常见的信号(SIGINT, SIGQUIT, SIGHUP, SIGPIPE, SIGCHLD);

    3.服务器在后台运行;

    4.使用C++实现;

     1 /**
     2   defs.h
     3 */
     4 #ifndef _DEFS_H_
     5 #define _DEFS_H_
     6 
     7 #include <signal.h>
     8 #include <assert.h>
     9 #include <iostream>
    10 
    11 #define PORT 8111
    12 #define MSG_LEN 1024
    13 
    14 typedef enum NETWORK_TYPE
    15 {
    16     NETWORK_TCP = 0,
    17     NETWORK_UDP = 1
    18 } NETWORK_TYPE;
    19 
    20 #endif    // _DEFS_H_
     1 /**
     2   server.h
     3 */
     4 #ifndef _CSERVER_H_
     5 #define _CSERVER_H_
     6 
     7 #include "defs.h"
     8 
     9 namespace webrtc {
    10 
    11 class CServer
    12 {
    13 public:
    14     CServer(int port, NETWORK_TYPE type);
    15     ~CServer();
    16 
    17 public:
    18     void registerSignals(int sig, void(*handle)(int));
    19     void run();
    20 
    21 private:
    22     class CInternal;
    23     CInternal*    m_internal;
    24 };
    25 
    26 }
    27 
    28 #endif    // _CSERVER_H_
     1 /**
     2   internal.h
     3 */
     4 #ifndef _INTERNAL_H_
     5 #define _INTERNAL_H_
     6 
     7 #include "server.h"
     8 #include <stdio.h>
     9 #include <unistd.h>
    10 #include <string.h>
    11 #include <strings.h>
    12 #include <sys/types.h>
    13 #include <sys/socket.h>
    14 #include <netinet/in.h>
    15 
    16 namespace webrtc
    17 {
    18 
    19 class CServer::CInternal
    20 {
    21 public:
    22     CInternal(int port, NETWORK_TYPE type);
    23     ~CInternal();
    24     
    25 public:
    26     void registerSignals(int sig, void(*handle)(int));
    27     bool start();
    28     void run();
    29 
    30 private:
    31     int m_port;
    32     NETWORK_TYPE m_type;
    33     int m_socket_fd;
    34     char *m_buff;
    35     struct sockaddr_in m_local_addr;
    36 };
    37 
    38 }    // end webrtc
    39 
    40 #endif    // _INTERNAL_H_
      1 /**
      2   server.cpp
      3 */
      4 #include "internal.h"
      5 #include <signal.h>
      6 
      7 namespace webrtc 
      8 {
      9 
     10 CServer::CInternal::CInternal(int port, NETWORK_TYPE type)
     11     : m_port(port)
     12     , m_type(type)
     13     , m_socket_fd(-1)
     14     , m_buff(NULL)
     15 {
     16     m_buff = new char[MSG_LEN];
     17 }
     18 
     19 CServer::CInternal::~CInternal()
     20 {
     21     if (m_buff != NULL) {
     22         delete[] m_buff;
     23         m_buff = NULL;
     24     }
     25 
     26     if (m_socket_fd > 0) {
     27         close(m_socket_fd);
     28         m_socket_fd = -1;
     29     }
     30 }
     31 
     32 bool CServer::CInternal::start()
     33 {
     34     m_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
     35     if (socket_fd == -1) {
     36         printf("can't create socket fd
    ");
     37         return false;
     38     }
     39 
     40     int on = 1;
     41     int ret = setsockopt(m_socket_fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
     42     if (ret == -1) {
     43         printf("faild to set socket option
    ");
     44     }
     45 
     46     bzero(&m_local_addr, sizeof(m_local_addr));
     47     m_local_addr.sin_family = AF_INET;
     48     m_local_addr.sin_port = htons(m_port);
     49     m_local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
     50     socklen_t addr_len = sizeof(struct sockaddr_in);
     51     ret = bind(m_socket_fd, (struct sockaddr *)&m_local_addr, addr_len);
     52     if (ret == -1) {
     53         printf("failed to bind addr
    ");
     54         return false;
     55     }
     56 
     57     int backlog = 10;
     58     ret = listen(m_socket_fd, backlog);
     59     if (ret == -1) {
     60         printf("failed listen
    ");
     61         return false;
     62     }
     63     printf("listening on port[%d]
    ", m_port);
     64 
     65     return true;
     66 }
     67 
     68 void CServer::CInternal::registerSignals(int sig, void(*handle)(int))
     69 {
     70     std::cout << "register sig:" << sig << std::endl;
     71     signal(sig, handle);
     72 }
     73 
     74 void CServer::CInternal::run()
     75 {
     76     if (!start()) {
     77         printf("start server failed, port[%d].
    ", m_po);
     78         return;
     79     }
     80 
     81     std::cout << "run..." << std::endl;
     82     int ret = -1;
     83     int accept_fd;
     84     struct sockaddr_in remote_addr;
     85     bzero(&remote_addr, sizeof(remote_addr));
     86     socklen_t addr_len = sizeof(struct sockaddr_in);
     87     while (true) {
     88         accept_fd = accept(m_socket_fd, (struct sockaddr *)&remoteaddr, &addr_len);
     89         if (accept_fd <= 0) 
     90             continue;
     91 
     92         while (true) {
     93             memset(m_buff, 0, sizeof(m_buff));
     94             ret = recv(accept_fd, (void *)in_buff, MESSAGE_LEN, 0);
     95             if (ret == 0) 
     96                 break;
     97 
     98             printf("recv:%s
    ", in_buff);
     99             send(accept_fd, (void *)in_buff, MESSAGE_LEN, 0);
    100         } // end while
    101 
    102         close(accept_fd);
    103     } //end while
    104 }
    105 
    106 CServer::CServer(int port, NETWORK_TYPE type)
    107     : m_internal(NULL)
    108 {
    109     m_internal = new CInternal(port, type);
    110     assert(m_internal != NULL);
    111 }
    112 
    113 CServer::~CServer()
    114 {
    115     delete m_internal;
    116     m_internal = NULL;
    117 }
    118 
    119 void CServer::registerSignals(int sig, void(*handle)(int))
    120 {
    121     if (m_internal != NULL)
    122     {
    123         m_internal->registerSignals(sig, handle);
    124     }
    125 }
    126 
    127 void CServer::run()
    128 {
    129     if (m_internal != NULL)
    130     {
    131         m_internal->run();
    132     }
    133 }
    134 
    135 }    // end webrtc
     1 /**
     2   tcpserver.cpp
     3 */
     4 #include <iostream>
     5 #include "server.h"
     6 
     7 using namespace webrtc;
     8 
     9 void sighandle(int sig) 
    10 {
    11     std::cout << "sig:" << sig << std::endl;
    12     if (sig == SIGINT)
    13     {
    14         _exit(0);
    15     }
    16 }
    17 
    18 int main(int argc, char* argv[])
    19 {
    20     CServer* server = new CServer(PORT, NETWORK_TCP);
    21     server->registerSignals(SIGINT, sighandle);
    22     server->registerSignals(SIGQUIT, sighandle);
    23     server->registerSignals(SIGCHLD, sighandle);
    24     server->registerSignals(SIGPIPE, sighandle);
    25     server->registerSignals(SIGHUP, sighandle);
    26 
    27     server->run();
    28 
    29     return 0;
    30 }
    31 
    32 # g++ -std=c++11 -g -o tcpserver tcpserver.cpp server.cpp
    33 # ./tcpserver
     1 /**
     2   client.h
     3 */
     4 #ifndef _CCLIENT_H_
     5 #define _CCLIENT_H_
     6 
     7 #include "defs.h"
     8 #include <iostream>
     9 
    10 namespace webrtc {
    11 
    12 class CClient
    13 {
    14 public:
    15     CClient();
    16     ~CClient();
    17 
    18 public:
    19     bool connect(const std::string& address, int port);
    20     void run();
    21 
    22 private:
    23     int m_socket_fd;
    24 };
    25 
    26 }
    27 
    28 #endif
     1 /**
     2   client.cpp
     3 */
     4 #include "client.h"
     5 #include <stdio.h>
     6 #include <string.h>
     7 #include <unistd.h>
     8 #include <sys/types.h>
     9 #include <sys/socket.h>
    10 #include <netinet/in.h>
    11 #include <arpa/inet.h>
    12 
    13 namespace webrtc
    14 {
    15 
    16 CClient::CClient()
    17     : m_socket_fd(-1)
    18 {}
    19 
    20 CClient::~CClient()
    21 {}
    22 
    23 bool CClient::connect(const std::string& address, int port)
    24 {
    25     int ret = -1;
    26     struct sockaddr_in server_addr;
    27     socklen_t addr_len;
    28 
    29     m_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    30     if (m_socket_fd < 0) {
    31         printf("failed create socket
    ");
    32         return false;
    33     }
    34 
    35     bzero(&server_addr, sizeof(server_addr));
    36     server_addr.sin_family = AF_INET;
    37     server_addr.sin_port = htons(port);
    38     server_addr.sin_addr.s_addr = inet_addr(address.c_str());
    39     addr_len  = sizeof(struct sockaddr_in);
    40     ret = ::connect(m_socket_fd, (struct sockaddr *)&server_addr, addr_len);
    41     if (ret < 0) {;
    42         return false;
    43     }
    44     printf("connect to server[%s:%d] success.
    ", address.c_str(), port);
    45 
    46     return true;
    47 }
    48 
    49 void CClient::run()
    50 {
    51     int ret = -1;
    52     char send_buf[MSG_LEN] = { 0 };
    53     char recv_buf[MSG_LEN] = { 0 };
    54     while (1) {
    55         memset(send_buf, 0, sizeof(send_buf));
    56         memset(recv_buf, 0, sizeof(recv_buf));
    57         gets(send_buf);
    58         if (strncmp(send_buf, "quit", 4) == 0)
    59             break;
    60 
    61         ret = send(m_socket_fd, send_buf, strlen(send_buf), 0);
    62         if (ret <= 0) {
    63             printf("failed send msg[%s]
    ", send_buf);
    64             break;
    65         }
    66 
    67         ret = recv(m_socket_fd, recv_buf, sizeof(recv_buf), 0);
    68         recv_buf[ret] = '';
    69         if (ret <= 0) {
    70             printf("recv zero msg
    ");
    71             continue;
    72         }
    73 
    74         printf("recv msg[%s]
    ", recv_buf);
    75     } // end while
    76 
    77     close(m_socket_fd);
    78 }
    79 
    80 }
     1 /**
     2   tcpclient.cpp
     3 */
     4 #include "defs.h"
     5 #include "client.h"
     6 #include <stdio.h>
     7 #include <signal.h>
     8 #include <unistd.h>
     9 
    10 void sighandler(int sig)
    11 {
    12     printf("received signal:%d
    ", sig);
    13     _exit(1);
    14 }
    15 
    16 int main(int argc, char* argv[])
    17 {
    18     if (argc != 3) {
    19         printf("usage ./client <ip address> <host port>
    ");
    20         return 1;
    21     }
    22 
    23     struct sigaction act, oact;
    24     act.sa_handler = sighandler;
    25     sigfillset(&act.sa_mask);
    26     act.sa_flags = 0;
    27     sigaction(SIGINT, &act, &oact);
    28     sigaction(SIGQUIT, &act, &oact);
    29 
    30     webrtc::CClient client;
    31     if (!client.connect(argv[1], atoi(argv[2]))) {
    32         printf("connect to server[%s:%s] failed.
    ", argv[1], argv[2]);
    33         return 2;
    34     }
    35 
    36     client.run();
    37 
    38     return 0;
    39 }
    40 
    41 # g++ -std=c++11 -g -o tcpclient tcpclient.cpp client.cpp
    42 # ./tcpclient 127.0.0.1 8111

  • 相关阅读:
    Button 使用Command 按钮置灰未更新
    C# TextBox 焦点
    MultiTigger 绑定异常处理
    C# 获取程序路径
    Linux 权限设置chmod
    WPF SpreadSheetGear电子表单
    WPF 窗口
    Excel公式 提取文件路径后缀
    C#/VB.NET 获取电脑属性(硬盘ID、硬盘容量、Cpu序列号、MAC地址、系统类型)
    DevExpress Carousel 设置水平滑动列表
  • 原文地址:https://www.cnblogs.com/sip-inaction/p/13127154.html
Copyright © 2011-2022 走看看