TCP 相关实验TCP 相关实验
理解 listen 的第二个参数
对于服务器, listen 的第二个参数设置为 2, 并且不调用 accept
test_server.cc
#include "tcp_socket.hpp"
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("Usage ./test_server [ip] [port]\n");
return 1;
}
TcpSocket sock;
bool ret = sock.Bind(argv[1], atoi(argv[2]));
if (!ret) {
return 1;
}
ret = sock.Listen(2);
if (!ret) {
return 1;
}
// 客户端不进行 accept
while (1) {
sleep(1);
}
return 0; }
test_client.cc
#include "tcp_socket.hpp"
int main(int argc, char* argv[]) {
if (argc != 3) {
printf("Usage ./test_client [ip] [port]\n");
return 1;
}
TcpSocket sock;
bool ret = sock.Connect(argv[1], atoi(argv[2]));
if (ret) {
printf("connect ok\n");
} else {
printf("connect failed\n");
}
while (1) {
sleep(1);
}
return 0; }
此时启动
3
个客户端同时连接服务器
,
用
netstat
查看服务器状态
,
一切正常
.
但是启动第四个客户端时
,
发现服务器对于第四个连接的状态存在问题了
tcp 3 0 0.0.0.0:9090 0.0.0.0:* LISTEN
9084/./test_server
tcp 0 0 127.0.0.1:9090 127.0.0.1:48178 SYN_RECV -
tcp 0 0 127.0.0.1:9090 127.0.0.1:48176 ESTABLISHED -
tcp 0 0 127.0.0.1:48178 127.0.0.1:9090 ESTABLISHED
9140/./test_client
tcp 0 0 127.0.0.1:48174 127.0.0.1:9090 ESTABLISHED
9087/./test_client
tcp 0 0 127.0.0.1:48176 127.0.0.1:9090 ESTABLISHED
9088/./test_client
tcp 0 0 127.0.0.1:48172 127.0.0.1:9090 ESTABLISHED
9086/./test_client
tcp 0 0 127.0.0.1:9090 127.0.0.1:48174 ESTABLISHED -
tcp 0 0 127.0.0.1:9090 127.0.0.1:48172 ESTABLISHED -
客户端状态正常
,
但是服务器端出现了
SYN_RECV
状态
,
而不是
ESTABLISHED
状态
这是因为, Linux内核协议栈为一个tcp连接管理使用两个队列
1.
半链接队列(用来保存处于
SYN_SENT
和
SYN_RECV
状态的请求)
2.
全连接队列(
accpetd
队列)(用来保存处于
established
状态,但是应用层没有调用
accept
取走的请求)
而全连接队列的长度会受到
listen
第二个参数的影响
全连接队列满了的时候
,
就无法继续让当前连接的状态进入
established
状态了
.
这个队列的长度通过上述实验可知
,
是
listen
的第二个参数
+ 1
问题:为什么要有队列,为什么队列不能太长?
![](https://img-blog.csdnimg.cn/b9ba00a2849b45d5a0517cc4dab683d7.png)