Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 394|回复: 0

[默认分类] 服务器后台TCP连接存活问题

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-6-11 10:00:05 | 显示全部楼层 |阅读模式


      公司的服务器后台部署在某一个地方,接入的是用户的APP,而该地方的网络信号较差,导致了服务器后台在运行一段时间后用户无法接入,那边的同事反馈使用netstat查看系统,存在较多的TCP连接。
      1. 问题分析
        首先在公司内部测试服务器上部署,使用LoadRunner做压力测试,能正常运行,然后那边的同事反馈该地方信号较差。考虑到接入的问题,有可能接入进程的FD资源耗尽,导致accept失败。推论的依据是对于TCP连接来说,如果客户端那边由于一些异常情况导致断网而未能向服务器发起FIN关闭消息,服务端这边若没有设置存活检测的话,该连接会存在(存活时间暂未测)。
      2. 实验测试
        这里简单地写了一个服务端的程序,主要功能是回应,即接受一个报文(格式:2Byte报文长度+报文内容),然后原封不动将报文内容发回客户端。
      
      
       
       
    1.   1 #include <stdio.h>
    2.   2 #include <sys/types.h>
    3.   3 #include <sys/socket.h>
    4.   4 #include <sys/epoll.h>
    5.   5 #include <unistd.h>
    6.   6 #include <pthread.h>
    7.   7 #include <stdlib.h>
    8.   8 #include <string.h>
    9.   9 #include <arpa/inet.h>
    10. 10
    11. 11 int g_epfd;
    12. 12
    13. 13 int InitServer( unsigned short port )
    14. 14 {
    15. 15     int nServerFd = socket( AF_INET, SOCK_STREAM, 0 );
    16. 16
    17. 17     struct sockaddr_in addr;
    18. 18     memset( &addr, 0, sizeof(addr) );
    19. 19
    20. 20     addr.sin_family = AF_INET;
    21. 21     addr.sin_port = htons( port );
    22. 22     addr.sin_addr.s_addr = 0;
    23. 23
    24. 24     if ( bind( nServerFd, (struct sockaddr *)&addr, sizeof(addr) ) <0 )
    25. 25     {
    26. 26         printf("bind error\n");
    27. 27         exit(-1);
    28. 28     }
    29. 29
    30. 30     if ( listen( nServerFd, 128 ) < 0 )
    31. 31     {
    32. 32         printf("listen error\n");
    33. 33         exit(-1);
    34. 34     }
    35. 35
    36. 36     return nServerFd;
    37. 37 }
    38. 38
    39. 39 int AddFd( int epfd, int nFd , int nOneShot)
    40. 40 {
    41. 41     struct epoll_event event;
    42. 42     memset( &event, 0, sizeof( event) );
    43. 43
    44. 44     event.data.fd = nFd;
    45. 45     event.events |= EPOLLIN | EPOLLRDHUP | EPOLLET;
    46. 46
    47. 47     if ( nOneShot ) event.events |= EPOLLONESHOT;
    48. 48
    49. 49     return epoll_ctl( epfd, EPOLL_CTL_ADD, nFd, &event );
    50. 50 }
    51. 51
    52. 52 int ResetOneShot( int epfd, int nFd )
    53. 53 {
    54. 54     struct epoll_event event;
    55. 55     memset( &event, 0, sizeof(event) );
    56. 56
    57. 57     event.data.fd = nFd;
    58. 58     event.events |= EPOLLIN | EPOLLRDHUP | EPOLLONESHOT;
    59. 59
    60. 60     return epoll_ctl( epfd, EPOLL_CTL_MOD, nFd, &event);
    61. 61 }
    62. 62
    63. 63 void * ReadFromClient( void * arg )
    64. 64 {
    65. 65     int nClientFd = (int)arg;
    66. 66     unsigned char buf[1024];
    67. 67     const int nBufSize = sizeof( buf );
    68. 68     int nRead;
    69. 69     int nTotal;
    70. 70     int nDataLen;
    71. 71
    72. 72     printf("ReadFromClient Enter\n");
    73. 73
    74. 74     if ( (nRead = read( nClientFd, buf, 2 )) != 2 )
    75. 75     {
    76. 76         printf("Read Data Len error\n");
    77. 77         pthread_exit(NULL);
    78. 78     }
    79. 79
    80. 80     nDataLen = *(unsigned short *)buf;
    81. 81     printf("nDataLen [%d]\n", nDataLen);
    82. 82     nDataLen = buf[0]*256 + buf[1];
    83. 83     printf("nDataLen [%d]\n", nDataLen);
    84. 84
    85. 85     nRead = 0;
    86. 86     nTotal = 0;
    87. 87     while( 1 )
    88. 88     {
    89. 89         nRead = read( nClientFd, buf + nRead, nBufSize );
    90. 90         if ( nRead < 0 )
    91. 91         {
    92. 92             printf("Read Data error\n");
    93. 93             pthread_exit( NULL );
    94. 94         }
    95. 95         nTotal += nRead;
    96. 96         if ( nTotal >= nDataLen )
    97. 97         {
    98. 98             break;
    99. 99         }
    100. 100     }
    101. 101     printf("nTotal [%d]\n", nTotal);
    102. 102
    103. 103     sleep(5);
    104. 104
    105. 105     int nWrite = write( nClientFd, buf, nTotal );
    106. 106     printf("nWrite[%d]\n", nWrite);
    107. 107
    108. 108     printf("Not Write ResetOneShot [%d]\n", ResetOneShot(g_epfd, nClientFd));
    109. 109
    110. 110     return NULL;
    111. 111 }
    112. 112
    113. 113 int main(int argc, char const *argv[])
    114. 114 {
    115. 115     int i;
    116. 116     int nClientFd;
    117. 117     pthread_t tid;
    118. 118     struct epoll_event events[1024];
    119. 119
    120. 120     int nServerFd = InitServer( 7777 );
    121. 121     if ( nServerFd < 0 )
    122. 122     {
    123. 123         perror( "nServerFd" );
    124. 124         exit(-1);
    125. 125     }
    126. 126
    127. 127     int epfd = epoll_create( 1024 );
    128. 128
    129. 129     g_epfd = epfd;
    130. 130
    131. 131     int nReadyNums;
    132. 132
    133. 133     if ( AddFd( epfd, nServerFd, 0 ) < 0 )
    134. 134     {
    135. 135         printf("AddFd error\n");
    136. 136         exit(-1);
    137. 137     }
    138. 138
    139. 139     while( 1 )
    140. 140     {
    141. 141          nReadyNums = epoll_wait( epfd, events, 1024, -1 );
    142. 142
    143. 143          if ( nReadyNums < 0 )
    144. 144          {
    145. 145              printf("epoll_wait error\n");
    146. 146              exit(-1);
    147. 147          }
    148. 148
    149. 149          for ( i = 0; i <  nReadyNums; ++i)
    150. 150          {
    151. 151              if ( events[i].data.fd == nServerFd )
    152. 152              {
    153. 153                  nClientFd = accept( nServerFd, NULL, NULL );
    154. 154
    155. 155                  AddFd( epfd, nClientFd, 1 );
    156. 156
    157. 157              }else if ( events[i].events & EPOLLIN )
    158. 158              {
    159. 159                 // Can be implemented by threadpool
    160. 160                  //Read data from client
    161. 161                 pthread_create( &tid, NULL, ReadFromClient, (void *)(events[i].data.fd) );
    162. 162
    163. 163              }else if ( events[i].events & EPOLLRDHUP )
    164. 164              {
    165. 165                  //Close By Peer
    166. 166                 printf("Close By Peer\n");
    167. 167                 close( events[i].data.fd );
    168. 168              }else
    169. 169              {
    170. 170                 printf("Some thing happened\n");
    171. 171              }
    172. 172
    173. 173          }
    174. 174     }
    175. 175
    176. 176     return 0;
    177. 177 }
    复制代码

      
       
       
      
       
       
      测试内容:
      注:客户端IP: 192.168.10.108  服务器IP&Port: 192.168.10.110:7777
       
      a. 客户端发送一个报文至服务端,然后断网。(这里对程序做了点改动,这次实验注释了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
       
      



      

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-21 00:18 , Processed in 0.438112 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表