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& ...
随机推荐
- apache kafka系列之Producer处理逻辑
最近研究producer的负载均衡策略,,,,我在librdkafka里边用代码实现了partition 值的轮询方法,,,但是在现场验证时,他的负载均衡不起作用,,,所以来找找原因: 下文是一篇描 ...
- 树莓派进阶之路 (027) - 在Linux中增加swap空间
原贴地址:http://blog.csdn.net/chinalinuxzend/article/details/1759593 在Linux中增加swap空间 在安装Linux的时候,不知道swa ...
- ubuntu下制作u盘启动盘
ubuntu12.04下成功制作了ubuntu13.10 U盘启动盘. 成功 ubuntu14.04下成功制作了centos.7 U盘启动盘.成功 1.安装u盘制作工具unetbootin sudo ...
- block(三)揭开神秘面纱(上)-b
block到底是什么 我们使用clang的rewrite-objc命令来获取转码后的代码. 1.block的底层实现 我们来看看最简单的一个block: [caption id="attac ...
- Docker容器相互访问
原文地址:https://blog.csdn.net/subfate/article/details/81396532?utm_source=copy 很多时候,同一台机器上,需要运行多个docker ...
- 【Linux】字符转换命令join
join 看字面上的意义 (加入/参加) 就可以知道,他是在处理两个文件之间的数据,而且,主要是在处理『两个文件当中,有 "相同数据" 的那一行,才将他加在一起』的意思.我们利用底 ...
- 解决WIN32窗口不响应WM_LBUTTONDBLCLK消息
原文链接: http://www.cnblogs.com/xukaixiang/archive/2012/05/27/2520059.html 今天在做一个软件时,发现win32创建的窗体不能响应WM ...
- VC CListCtrl 第一列列宽自适应
原文链接: http://www.cnblogs.com/sephil/archive/2011/04/03/2004384.html 今天用VC写工具的时候用到CListView,并且ListCtr ...
- Facade 设计模式
目的 在一个子系统的一组接口上提供一个统一的接口.Facade 设计模式定义了一个更高级别的接口,使子系统更容易使用. 通过一个更加简洁的接口来包装一个复杂的子系统. 解决的问题 客户端需要一个简化的 ...
- 【转载并整理】mysql 1293错误 建表两个timestamp
http://www.jb51.net/article/50878.htm 这里要使用到mysql的触发器