listen的参数backlog的意义


/*
* gcc -std=c99 -o tcpCli ./tcpCli.c -lpthread
*/
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h> const int PORT = ; void* func(void *arg)
{
int fd = socket(AF_INET, SOCK_STREAM, );
if (fd == -)
{
perror("socket");
return (void*);
} struct sockaddr_in addr;
memset(&addr, , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(PORT); // get send buffer size
int iWBufSize;
socklen_t optLen = sizeof(iWBufSize);
getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &iWBufSize, &optLen);
printf("Write buffer size = %d\n", iWBufSize); int iRBufSize;
optLen = sizeof(iRBufSize);
getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &iRBufSize, &optLen);
printf("Read buffer size = %d\n", iRBufSize); if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) != )
{
perror("connect");
return (void*);
} char buf[] = "hello world!";
int iCount = ;
while ()
{
sprintf(buf, "%d", iCount);
int iRet = send(fd, buf, strlen(buf), );
if (iRet == -)
{
perror("sendto");
break;
}
else
{
// printf("Send data len [%d]\n", iRet);
iCount++;
}
if (iCount % == )
{
// printf("Send package count %d\n", iCount);
sleep();
}
}
printf("Send package count %d\n", iCount);
close(fd); return (void*);
}
int main(int argc, char **argv)
{
if (argc != )
{
printf("Usage:%s thread_num\n", argv[]);
return ;
} int iThreadNum = atoi(argv[]);
printf("ThreadNum [%d]\n", iThreadNum);
pthread_t *pTid = (pthread_t*)malloc(sizeof(pthread_t) * iThreadNum);
for (int i = ; i < iThreadNum; ++i)
{
pthread_create(&pTid[i], NULL, func, NULL);
} for (int i = ; i < iThreadNum; ++i)
{
pthread_join(pTid[i], NULL);
} return ;
}
tcpCli
/*
* gcc -o tcpSvr ./tcpSvr.c
*/
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pthread.h> const int PORT = ; int main(int argc, char **argv)
{
int fd = socket(AF_INET, SOCK_STREAM, );
if (fd == -)
{
perror("socket");
return errno;
} printf("Port %d\n", PORT);
struct sockaddr_in addr;
memset(&addr, , sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(PORT); if (- == bind(fd, (struct sockaddr*)&addr, sizeof(addr)))
{
perror("bind");
return errno;
} if (- == listen(fd, ))
{
perror("listen");
return errno;
} struct sockaddr_in cli_addr;
socklen_t cli_addr_len = sizeof(cli_addr);
sleep(); int client = accept(fd, (struct sockaddr*)&cli_addr, &cli_addr_len);
if (client < )
{
perror("accept");
return errno;
} char buf[];
int iCount = ;
int iZero = ;
while()
{
memset(buf, , );
int iRet = recv(client, buf, , );
printf("Recv package count[%d]\t", iCount);
printf("recv content [%s]\n", buf);
iRet = send(client, buf, iRet, ); iRet = iRet/iZero;
}
close(fd); return ;
}
tcpSvr
实验结果:
执行:tcpCli 15 的结果

这是使用grep过滤了tcpSvr的显示结果:

这是使用grep过滤了tcpCli的显示结果:

这是过了一段时间后,tcpCli输出的结果:

TCP状态转移图:

然后根据这些结果以及TCP状态转移图,可以得出如下结论:



这段解释的意思就是,当服务端未处理连接队列满的时候,它就会丢掉client端发送的三次握手中的最后一个ACK包,这就会导致,client端以为自己已经建立连接了,但是实际在server端没有连接,同时也解释了tcpdump抓包看到的,为什么server一直不停的发送三次握手的第二次数据包(SYN+ACK)。
另外,关于这种类似的问题,就像知乎浅墨说的,策略在不停的改变,不要听信网上别人的说法,自己动手试一下就可以了。
listen的参数backlog的意义的更多相关文章
- socket的同步异步的性能差别,以及listen的参数backlog
先说listen的参数backlog,同步系统中分别设置为5,512,1024的跑分情况 跑分工具apache的ab,参数为:ab -n50000 -c300 backlog=5跑分结果 Reques ...
- [TCP/IP] TCP在listen时的参数backlog的意义
linux内核中会维护两个队列: 1)未完成队列:接收到一个SYN建立连接请求,处于SYN_RCVD状态 2)已完成队列:已完成TCP三次握手过程,处于ESTABLISHED状态 3)当有一个S ...
- listen函数里面backlog的意义以及各种情况
先看了这篇: http://www.cppblog.com/thisisbin/archive/2010/02/07/107444.html 里面说了会维护两个队列,established 和 syn ...
- Linux中,Tomcat 怎么承载高并发(深入Tcp参数 backlog)
一.前言 这两天看tomcat,查阅 tomcat 怎么承载高并发时,看到了backlog参数.我们知道,服务器端一般使用mq来减轻高并发下的洪峰冲击,将暂时不能处理的请求放入队列,后续再慢慢处理.其 ...
- dojo表格分页之各个参数代表的意义(一)
下面是dojo表格分页参数代表的意义 //每页可以显示10/15/20/25/30条记录 (1)pageSizes: [10, 15, 20, 25,30], //每页显示的记录从多少到多少,共多少条 ...
- socket listen参数中的backlog 的意义!
服务器监听时,在每次处理一个客户端的连接时是需要一定时间的,这个时间非常的短(也许只有1ms 或者还不到),但这个时间还是存在的.而这个backlog 存在的意义就是:在这段时间里面除了第一个连接请求 ...
- tcp/ip协议listen函数中backlog参数的含义与php-fpm的502 Bad Gateway
To understand the backlog argument, we must realize that for a given listening socket, the kernel ma ...
- linux tcp listen函数的参数backlog
1 listen函数(http://man7.org/linux/man-pages/man2/listen.2.html) int listen(int sockfd, int backlog); ...
- listen()函数中backlog参数分析
实例分析1 将服务器端的listen函数backlog设置为2,用20个客户端与服务器建立连接,查看连接的建立情况. 服务器代码: #include <stdio.h> #include& ...
随机推荐
- Linux系统vi编辑器提示E325: ATTENTION的解决方法
非正常关闭文件会报这样的警告信息, 原因是系统产生了一个.swp的文件. 删除就行了.(前提是确认.swp文件没用了.) 例如: rm -f /etc/.shadowsocks.json.swp 详情 ...
- 线程同步之mutex和event区别
之前只是用过 关键段来对同进程不同线程进行互斥,防止对同一份资源或代码段的竞争: mutex可以理解为不同进程或者同一进程内防止对同一份资源的竞争: event更多的是同步,当然也是不同进程或者同一进 ...
- Linux 日志切割工具cronolog详解
一.前言 二.cronolog 简介 三.cronolog 特点 四.cronolog 安装 五.cronolog 使用 六.cronolog 总结 注,操作系统 CentOS 6.4 x86_64, ...
- mysqlsla快速入门
小强软件测试,因为不是天生丽质,所以必须天生励志. 性能.python自动化班长期招生,咨询QQ:2083503238 官网:http://xqtesting.sxl.cn QQ群:229390571 ...
- io分析神器blktrace
一.概述 [许久之前就用过blktrace,现整理如下] 从linux 一个完整的IO入手分析: 一个I/O请求进入block layer之后,可能会经历下面的过程: Remap: 可能被DM(Dev ...
- android 当ListView滚动时自动调用 onCheckedChanged 导致CheckBox 状态不停变化 的解决办法
今天在做一个含有CheckBox 的ListView时,发现当初始化CheckBox的状态后, 滚动ListView,其中CheckBox 的选中状态不停的发生变化.最后发现原因是 ListView滚 ...
- 【Android】Android六种布局详解
这篇就对LinearLayout.RelativeLayout.自定义ViewGroup.FrameLayout.TableLayout.AbsoluteLayout六种布局进行详细的讲解. 1.Li ...
- Unicode和UTF的关系
目录结构: contents structure [+] 什么是USC UCS的编码方式 Unicode的来源 为什么需要Unicode Unicode的方式 Unicode和UTF UTF和Unic ...
- iOS-获取当前View所在的控制器
用一个分类,具体: .h #import <UIKit/UIKit.h> @interface UIView (CurrentController) /** 获取当前View的控制器对象 ...
- Spring Cloud问题分析
基于Spring Cloud框架开发时,经常会碰到各种开发问题,那么碰到这些问题时如何去解决呢?下面描述基于Spring Cloud问题定位的基本思路,大概可以分为如下几步: 排查配置问题 环境问题 ...