服务器与客户端连接,客户端异常断掉之后服务器端口仍然被占用, 到最后是不是服务器端达到最大连接数就没法连接了?领导让我测试这种情况,我用自己的电脑当TCP Client,虚拟机当服务器,连接之后能正常通信,每次拔掉网线断开,5次之后就不能连接了(我的服务器设置最大连接数就是5)。具体如下:1:用模拟软件Commix模拟TCP Client,连接服务器。

<ignore_js_op>

2:用服务器端监听端口1234。重复打开关闭TCP Client的端口,服务器显示如下图所示:
<ignore_js_op>

1——5次可以正常连接,5次完成之后出现如下问题:
<ignore_js_op> 
请问怎么解决这一问题,让服务器端自动清除已断掉的连接。
socket程序如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MYPORT 1234    // the port users will be connecting to

#define BACKLOG 5     // how many pending connections queue will hold

#define BUF_SIZE 200

int fd_A[BACKLOG];    // accepted connection fd
int conn_amount;    // current connection amount

void showclient()
{
    int i;
    printf("client amount: %d\n", conn_amount);
    for (i = 0; i < BACKLOG; i++) {
        printf("[%d]:%d  ", i, fd_A);
    }
    printf(
"\n\n");
}

int main(void)
{
    int sock_fd, new_fd;  // listen on sock_fd, new connection on new_fd
    struct sockaddr_in server_addr;    // server address information
    struct sockaddr_in client_addr; // connector's address information
    socklen_t sin_size;
    int yes = 1;
    char buf[BUF_SIZE];
    int ret;
    int i;

if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
        perror("setsockopt");
        exit(1);
    }
    
    server_addr.sin_family = AF_INET;         // host byte order
    server_addr.sin_port = htons(MYPORT);     // short, network byte order
    server_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
    memset(server_addr.sin_zero, '\0', sizeof(server_addr.sin_zero));

if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("bind");
        exit(1);
    }

if (listen(sock_fd, BACKLOG) == -1) {
        perror("listen");
        exit(1);
    }

printf("listen port %d\n", MYPORT);

fd_set fdsr;
    int maxsock;
    struct timeval tv;

conn_amount = 0;
    sin_size = sizeof(client_addr);
    maxsock = sock_fd;
    while (1) {
        // initialize file descriptor set
        FD_ZERO(&fdsr);
        FD_SET(sock_fd, &fdsr);

// timeout setting
        tv.tv_sec = 30;
        tv.tv_usec = 0;

// add active connection to fd set
        for (i = 0; i < BACKLOG; i++) {
            if (fd_A != 0) {
                FD_SET(fd_A&fdsr);
            }
        }

ret = select(maxsock + 1, &fdsr, NULL, NULL, &tv);
        if (ret < 0) {
            perror("select");
            break;
        } else if (ret == 0) {
            printf("timeout\n");
            continue;
        }

// check every fd in the set
        for (i = 0; i < conn_amount; i++) {
            if (FD_ISSET(fd_A&fdsr)) {
                ret = recv(fd_A, buf, sizeof(buf), 0);
                if (ret <= 0) {        // client close
                    printf("client[%d] close\n", i);
                    close(fd_A);
                    FD_CLR(fd_A
&fdsr);
                    fd_A = 0;
                } else {        // receive data
                    if (ret < BUF_SIZE)
                        memset(&buf[ret], '\0', 1);
                    printf("client[%d] send:%s\n", i, buf);
                }
            }
        }

// check whether a new connection comes
        if (FD_ISSET(sock_fd, &fdsr)) {
            new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);
            if (new_fd <= 0) {
                perror("accept");
                continue;
            }

// add to fd queue
            if (conn_amount < BACKLOG) {
                fd_A[conn_amount++] = new_fd;
                printf("new connection client[%d] %s:%d\n", conn_amount,
                        inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
                if (new_fd > maxsock)
                    maxsock = new_fd;
            }
            else {
                printf("max connections arrive, exit\n");
                send(new_fd, "bye", 4, 0);
                close(new_fd);
                break;
            }
        }
        showclient();
    }

// close other connections
    for (i = 0; i < BACKLOG; i++) {
        if (fd_A != 0) {
            close(fd_A);
        }
    }

exit(0);
}

linux 服务器与客户端异常断开连接问题的更多相关文章

  1. [转]Linux服务器上11种网络连接状态 和 TCP三次握手/四次挥手详解

    一.Linux服务器上11种网络连接状态: 图:TCP的状态机 通常情况下:一个正常的TCP连接,都会有三个阶段:1.TCP三次握手;2.数据传送;3.TCP四次挥手. 注:以下说明最好能结合”图:T ...

  2. Tcp服务端判断客户端是否断开连接

    今天搞tcp链接弄了一天,前面创建socket,绑定,监听等主要分清自己的参数,udp还是tcp的.好不容易调通了,然后就是一个需求,当客户端主动断开连接时,服务端也要断开连接,这样一下次客户端请求链 ...

  3. 查询linux服务器有哪些IP在连接

    查询linux服务器有哪些IP在连接 netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n 查看linux的 ...

  4. linux服务器ntp客户端配置【转】

    转自:https://www.cnblogs.com/kerrycode/archive/2015/08/20/4744804.html 在Linux系统中,为了避免主机时间因为在长时间运行下所导致的 ...

  5. 一台Linux服务器可以负载多少个连接?

    首先我们来看如何标识一个TCP连接?系统是通过一个四元组来识别,(src_ip,src_port,dst_ip,dst_port)即源IP.源端口.目标IP.目标端口.比如我们有一台服务192.168 ...

  6. [转]关于HTTP服务器每个客户端2个连接的限制

    这两天猫在家里搞一个多线程的断点续传得C#程序,发现同时只能开2个线程下载,其他的线程一律要等待,这样就导致下载大文件时其他线程经常超时,郁闷好久.今天回公司无意中发现了一个帖子,终于真相大白了, 现 ...

  7. 微软云Linux服务器 Mysql、tomcat远程连接错误解决办法

    在微软云linux服务器成功配置好mysql.tomcat,通过外部链接却发现一直错误.Mysql 一直提示错误代码2003, tomcat连接一直提示EOF. 反复检查配置都无问题,最后得知是微软云 ...

  8. 第一次项目上Linux服务器(一:远程连接服务器)

    一.准备工作 1.Linux服务器一台,以及服务器ip.用户名.密码 2.安装xfttp和xshell软件,资源链接,百度云链接:https://pan.baidu.com/s/1vwnlbBpmjX ...

  9. 【转】关于HTTP服务器每个客户端2个连接的限制

    http://www.cnblogs.com/lishenglyx/archive/2010/01/07/1641190.html 这两天猫在家里搞一个多线程的断点续传得C#程序,发现同时只能开2个线 ...

随机推荐

  1. CF643E Bear and Destroying Subtrees

    题解 我们可以先写出\(dp\)式来. 设\(dp[u][i]\)表示以\(u\)为根的子树深度不超过\(i-1\)的概率 \(dp[u][i]=\prod (dp[v][i-1]+1)*\frac{ ...

  2. 3D Computer Grapihcs Using OpenGL - 09 Enable Depth Test

    启用Depth Test OpenGL是个3D绘图API,也就是说不只有xy坐标轴,还有第三个坐标轴z,z轴的方向是垂直于屏幕,指向屏幕内. 靠近人眼的方向是负方向,标准化设备坐标的最小值是-1, 最 ...

  3. SpringCloud 教程 (五) 断路器监控(Hystrix Dashboard)

    一.Hystrix Dashboard简介 在微服务架构中为例保证程序的可用性,防止程序出错导致网络阻塞,出现了断路器模型.断路器的状况反应了一个程序的可用性和健壮性,它是一个重要指标.Hystrix ...

  4. 小程序封装wx.request,以及调用

    1.新建一个api目录,与pages同级 2.在api目录下新建一个api.js文件 3.编写代码 const host = 'http://test.test.cn' const wxRequest ...

  5. Oracle Or子句

    Oracle Or子句 作者:初生不惑 Oracle基础 评论:0 条 Oracle技术QQ群:175248146 在本教程中,我们来学习如何使用Oracle OR运算符来组合两个或更多的布尔表达式. ...

  6. VMware 15 搭建win 10 实操步骤+共享文件+激活操作

    写于:2018.12.22 一.简介: VMware 15 里搭建win 10是件很坑的事.我尝试了3种方法,最后才搭建成功.为了不让网友们不在走我走过的坑,特写了本文.   坑一:用老毛桃.大白菜搭 ...

  7. WIN10系统和压缩内存占用磁盘过高的解决方案(亲测有效)

    系统和压缩内存磁盘占用过高的解决方案 最近一段时间玩游戏看视频经常莫名的卡顿,观察发现电脑卡的时候,WIN10进程中的"系统和压缩内存"一项占用了近100%的磁盘空间. 百度搜索到 ...

  8. TCP报文段首部格式详解

    TCP首部格式   格式字段详解   源端口.目标端口: 计算机上的进程要和其他进程通信是要通过计算机端口的,而一个计算机端口某个时刻只能被一个进程占用,所以通过指定源端口和目标端口,就可以知道是哪两 ...

  9. h5离线缓存

    离线缓存:application cache 什么是离线缓存: 离线缓存可以将站点的一些文件缓存到本地,它是浏览器自己的一种机制,将需要的文件缓存下来,以便后期即使没链接网络,被缓存的页面也可以展示 ...

  10. python字典小知识

    字典的小知识dic = {"name": "tom", "age": 23, "price": 110}# 01:提取键 ...