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内核的ioctl函数学习
Linux内核的ioctl函数学习 来源:Linux公社 作者:Linux 我这里说的ioctl函数是在驱动程序里的,因为我不知道还有没有别的场合用到了ioctl, 所以就规定了我们讨论的范围.为什 ...
- Linux下网卡混杂模式设置和取消
工作中发现一个网卡工作状态不对了,查看了一下,发现这个网卡和正常工作的网卡 信息不一样,它显示的居然是混杂模式,而正常工作的是 running 模式 ,所以来了解下混杂模式怎么取消... 下文来自 ...
- nginx配置文件结构,语法,配置命令解释
摘要: nginx的配置文件类似于一门优雅的编程语言,弄懂了它的规范就可以自定义配置文件了,这个很重要~ 1,结构分析 nginx配置文件中主要包括六块:main,events,http,server ...
- mongodb常用命令小结
一.基于条件的查询 db.getCollection('monitor_log') .find({"requestUrl" : /app\/v1\/findcards\/cn/, ...
- [MSP430] 对MSP430单片机__delay_cycles精确延时的说明及改正
在这里, 我来讨论一下关于MSP430单片机使用__delay_cycles延时的问题. IAR for MSP430编译器提供了一个编译器内联的精确延时函数(并非真正的 函数)以提供用户精确延时使用 ...
- C# 禁止datagridview 自动产生列
dataGridView1.AutoGenerateColumns = false;
- 公网用户接入NAT后面的freeswitch配置
大致网络示意和终端号码: 客户端侧: 终端号码(1019)终端IP(192.168.1.15)+ 网关(192.168.1.1) + 路由器公网IP(动态地址) 服务器侧: 防火墙(181.92.2. ...
- Linux 4.10中两个新特性与我的一段故事
今早5点半起来没有開始写文章,而是去西湾红树林连跑带走折腾了将近20公里.回来后就8点多了...洗了个澡之后坐稳当.開始写一段关于我的故事. 在2014年到2015年期间,我在负责研发一 ...
- C#基础第五天-作业答案-用DataTable制作名片集
.DataTable 实现 DataTable PersonCard = new DataTable(); //创建一个DataTable DataTable PersonCardCopy = new ...
- Django 时间与时区设置问题
django 时间与时区设置问题 在Django的配置文件settings.py中,有两个配置参数是跟时间与时区有关的,分别是TIME_ZONE和USE_TZ 如果USE_TZ设置为True时,Dja ...