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& ...
随机推荐
- 基本的RAID介绍
RAID是一个我们经常能见到的名词.但却因为很少能在实际环境中体验,所以很难对其原理 能有很清楚的认识和掌握.本文将对RAID技术进行介绍和总结,以期能尽量阐明其概念. RAID全称为独立磁盘冗余阵列 ...
- Elasticstack 5.1.2 集群日志系统部署及实践
Elasticstack 5.1.2 集群日志系统部署及实践 一.ELK Stack简介 ELK Stack 是Elasticsearch.Logstash.Kibana三个开源软件的组合,在实时数据 ...
- macOS SIP 权限设置
1.macOS SIP 权限设置 对于 macOS 10.11+ 用户,由于系统启用了 SIP(System Integrity Protection), 导致 root 用户也没有权限修改 /usr ...
- Oracle 12C -- clone a remote pdb
Connect to the remote CDB and prepare the remote PDB for cloning. SQL> select con_id,dbid,name,op ...
- 永久代 PermGen 简述
永久代(PermGen) 绝大部分 Java 程序员应该都见过 “java.lang.OutOfMemoryError: PermGen space “这个异常.这里的 “PermGen space” ...
- golang包time用法详解
在我们编程过程中,经常会用到与时间相关的各种务需求,下面来介绍 golang 中有关时间的一些基本用法,我们从 time 的几种 type 来开始介绍. 时间可分为时间点与时间段,golang 也不例 ...
- 码字工作者的发文姿势—— 用MWeb+Markdown Here+七牛 轻松实现多平台发布
码字工作者的发文姿势—— 用MWeb+Markdown Here+七牛 轻松实现多平台发布 1.对于写作你最头疼什么 对于大多数码字工作者来说,随时随地记录灵感,构思文章,集中书写,其实是一件令人 ...
- 最强 Android Studio 使用小技巧和快捷键总结
最强 Android Studio 使用小技巧和快捷键总结 写在前面 本文翻译自 Android Studio Tips by Philippe Breault,一共收集了62个 Android ...
- django -- 为模式增加方法
在django中模式中的方法是行级的.也就是说它操作是表里的行.不是整个表 一.模式定义: from django.db import models # Create your models here ...
- 全相FFT
作者:桂. 时间:2017-12-02 23:29:48 链接:http://www.cnblogs.com/xingshansi/p/7956491.html 一.相位提取 以正弦信号为例,x = ...