zoukankan      html  css  js  c++  java
  • server后台TCP连接存活问题

    公司的server后台部署在某一个地方,接入的是用户的APP,而该地方的网络信号较差,导致了server后台在执行一段时间后用户无法接入,那边的同事反馈使用netstat查看系统。存在较多的TCP连接。

    1. 问题分析

      首先在公司内部測试server上部署,使用LoadRunner做压力測试,能正常执行,然后那边的同事反馈该地方信号较差。考虑到接入的问题。有可能接入进程的FD资源耗尽,导致accept失败。推论的根据是对于TCP连接来说,假设client那边因为一些异常情况导致断网而未能向server发起FIN关闭消息,服务端这边若没有设置存活检測的话。该连接会存在(存活时间暂未測)。

    2. 实验測试

      这里简单地写了一个服务端的程序。主要功能是回应,即接受一个报文(格式:2Byte报文长度+报文内容),然后原封不动将报文内容发回client。

    复制代码
      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <sys/socket.h>
      4 #include <sys/epoll.h>
      5 #include <unistd.h>
      6 #include <pthread.h>
      7 #include <stdlib.h>
      8 #include <string.h>
      9 #include <arpa/inet.h>
     10 
     11 int g_epfd;
     12 
     13 int InitServer( unsigned short port )
     14 {
     15     int nServerFd = socket( AF_INET, SOCK_STREAM, 0 );
     16 
     17     struct sockaddr_in addr;
     18     memset( &addr, 0, sizeof(addr) );
     19 
     20     addr.sin_family = AF_INET;
     21     addr.sin_port = htons( port );
     22     addr.sin_addr.s_addr = 0;
     23 
     24     if ( bind( nServerFd, (struct sockaddr *)&addr, sizeof(addr) ) <0 )
     25     {
     26         printf("bind error
    ");
     27         exit(-1);
     28     }
     29 
     30     if ( listen( nServerFd, 128 ) < 0 )
     31     {
     32         printf("listen error
    ");
     33         exit(-1);
     34     }
     35 
     36     return nServerFd;
     37 }
     38 
     39 int AddFd( int epfd, int nFd , int nOneShot)
     40 {
     41     struct epoll_event event;
     42     memset( &event, 0, sizeof( event) );
     43 
     44     event.data.fd = nFd;
     45     event.events |= EPOLLIN | EPOLLRDHUP | EPOLLET;
     46 
     47     if ( nOneShot ) event.events |= EPOLLONESHOT;
     48 
     49     return epoll_ctl( epfd, EPOLL_CTL_ADD, nFd, &event );
     50 }
     51 
     52 int ResetOneShot( int epfd, int nFd )
     53 {
     54     struct epoll_event event;
     55     memset( &event, 0, sizeof(event) );
     56 
     57     event.data.fd = nFd;
     58     event.events |= EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
     59 
     60     return epoll_ctl( epfd, EPOLL_CTL_MOD, nFd, &event);
     61 }
     62 
     63 void * ReadFromClient( void * arg )
     64 {
     65     int nClientFd = (int)arg;
     66     unsigned char buf[1024];
     67     const int nBufSize = sizeof( buf );
     68     int nRead;
     69     int nTotal;
     70     int nDataLen;
     71 
     72     printf("ReadFromClient Enter
    ");
     73 
     74     if ( (nRead = read( nClientFd, buf, 2 )) != 2 )
     75     {
     76         printf("Read Data Len error
    ");
     77         pthread_exit(NULL);
     78     }
     79 
     80     nDataLen = *(unsigned short *)buf;
     81     printf("nDataLen [%d]
    ", nDataLen);
     82     nDataLen = buf[0]*256 + buf[1];
     83     printf("nDataLen [%d]
    ", nDataLen);
     84 
     85     nRead = 0;
     86     nTotal = 0;
     87     while( 1 )
     88     {
     89         nRead = read( nClientFd, buf + nRead, nBufSize );
     90         if ( nRead < 0 )
     91         {
     92             printf("Read Data error
    ");
     93             pthread_exit( NULL );
     94         }
     95         nTotal += nRead;
     96         if ( nTotal >= nDataLen )
     97         {
     98             break;
     99         }
    100     }
    101     printf("nTotal [%d]
    ", nTotal);
    102 
    103     sleep(5);
    104 
    105     int nWrite = write( nClientFd, buf, nTotal );
    106     printf("nWrite[%d]
    ", nWrite);
    107 
    108     printf("Not Write ResetOneShot [%d]
    ", ResetOneShot(g_epfd, nClientFd));
    109 
    110     return NULL;
    111 }
    112 
    113 int main(int argc, char const *argv[])
    114 {
    115     int i;
    116     int nClientFd;
    117     pthread_t tid;
    118     struct epoll_event events[1024];
    119 
    120     int nServerFd = InitServer( 7777 );
    121     if ( nServerFd < 0 )
    122     {
    123         perror( "nServerFd" );
    124         exit(-1);
    125     }
    126 
    127     int epfd = epoll_create( 1024 );
    128 
    129     g_epfd = epfd;
    130 
    131     int nReadyNums;
    132 
    133     if ( AddFd( epfd, nServerFd, 0 ) < 0 )
    134     {
    135         printf("AddFd error
    ");
    136         exit(-1);
    137     }
    138 
    139     while( 1 )
    140     {
    141          nReadyNums = epoll_wait( epfd, events, 1024, -1 );
    142 
    143          if ( nReadyNums < 0 )
    144          {
    145              printf("epoll_wait error
    ");
    146              exit(-1);
    147          }
    148 
    149          for ( i = 0; i <  nReadyNums; ++i)
    150          {
    151              if ( events[i].data.fd == nServerFd )
    152              {
    153                  nClientFd = accept( nServerFd, NULL, NULL );
    154 
    155                  AddFd( epfd, nClientFd, 1 );
    156 
    157              }else if ( events[i].events & EPOLLIN )
    158              {
    159                 // Can be implemented by threadpool
    160                  //Read data from client
    161                 pthread_create( &tid, NULL, ReadFromClient, (void *)(events[i].data.fd) );
    162 
    163              }else if ( events[i].events & EPOLLRDHUP )
    164              {
    165                  //Close By Peer
    166                 printf("Close By Peer
    ");
    167                 close( events[i].data.fd );
    168              }else
    169              {
    170                 printf("Some thing happened
    ");
    171              }
    172 
    173          }
    174     }
    175 
    176     return 0;
    177 }
    复制代码

     

     

    測试内容:

    注:clientIP: 192.168.10.108  serverIP&Port: 192.168.10.110:7777

     

    a. client发送一个报文至服务端,然后断网

    (这里对程序做了点修改。这次实验凝视了write响应,防止write影响測试,后面一个实验会使用write)。

    http://bjjzdx.tumblr.com
    http://bjbdzbyz.tumblr.com
    http://shbdzbyz.tumblr.com
    http://pp1fe.tumblr.com
    http://mo3ay.tumblr.com
    http://p155f.tumblr.com
    http://ff0xy.tumblr.com
    http://l0q6c.tumblr.com
    http://qnkso.tumblr.com
    http://yubml.tumblr.com
    http://ejubd.tumblr.com
    http://cjb2t.tumblr.com
    http://jgaey.tumblr.com
    http://l89mp.tumblr.com
    http://k1q63.tumblr.com
    http://l2bwz.tumblr.com
    http://u5zq9.tumblr.com
    http://iq4an.tumblr.com
    http://f2wla.tumblr.com
    http://u40ng.tumblr.com
    http://h4jfn.tumblr.com
    http://u6cuu.tumblr.com
    http://kztnc.tumblr.com
    http://w9c84.tumblr.com
    http://hpw9q.tumblr.com
    http://hj4wp.tumblr.com
    http://y9mok.tumblr.com
    http://vev1n.tumblr.com
    http://ev3db.tumblr.com
    http://w7raj.tumblr.com
    http://it5bt.tumblr.com
    http://qjelk.tumblr.com
    http://hyjlf.tumblr.com
    http://bp4xn.tumblr.com


  • 相关阅读:
    CSS学习(五)
    1. Git-2.12.0-64-bit .exe下载
    90.bower解决js的依赖管理
    89.[NodeJS] Express 模板传值对象app.locals、res.locals
    88.NODE.JS加密模块CRYPTO常用方法介绍
    87.node.js操作mongoDB数据库示例分享
    50.AngularJs directive详解及示例代码
    49.AngularJs 指令directive之controller,link,compile
    48.AngularJS ng-src 指令
    86.express里面的app.configure作用
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7402401.html
Copyright © 2011-2022 走看看