tcp socket的backlog参数

底层

tcp在内核的请求过程,其实就是tcp的三次握手:

1、client发送SYN到server,将状态修改为SYN_SEND,如果server收到请求,则将状态修改为SYN_RCVD,并把该请求放到syns queue队列中。
2、server回复SYN+ACK给client,如果client收到请求,则将状态修改为ESTABLISHED,并发送ACK给server。
3、server收到ACK,将状态修改为ESTABLISHED,并把该请求从syns queue中放到accept queue。

4、当服务器进程调用accept()方法时,从accept queue中获取头部的请求。

5、当accept queue为空时,服务器进程将睡眠,直到accept queue不为空时,进程才会被唤醒。

在linux系统内核中维护了两个队列:syns queue和accept queue

syns queue
用于保存半连接状态的请求,其大小通过/proc/sys/net/ipv4/tcp_max_syn_backlog指定,一般默认值是512,不过这个设置有效的前提是系统的syncookies功能被禁用。互联网常见的TCP SYN FLOOD恶意DOS攻击方式就是建立大量的半连接状态的请求,然后丢弃,导致syns queue不能保存其它正常的请求。

accept queue
用于保存全连接状态的请求,其大小通过/proc/sys/net/core/somaxconn指定,在使用listen函数时,内核会根据传入的backlog参数与系统参数somaxconn,取二者的较小值。

如果accpet queue队列满了,server将发送一个ECONNREFUSED错误信息Connection refused到client。

应用层

在netty实现中,backlog默认通过NetUtil.SOMAXCONN指定。

当然也可以通过option方法自定义backlog的大小。

backlog设置注意点

前面已经提到过,内核会根据somaxconn和backlog的较小值设置accept queue的大小,如果想扩大accept queue的大小,必须要同时调整这两个参数。

原文地址:

https://www.jianshu.com/p/e6f2036621f4

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,下面是一个简单的封装TcpSocket类的例子: ```c++ #include <iostream> #include <string> #include <cstring> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> class TcpSocket { public: TcpSocket() : m_sockfd(-1) {} ~TcpSocket() { close(); } bool create() { m_sockfd = socket(AF_INET, SOCK_STREAM, 0); if (m_sockfd == -1) { return false; } return true; } bool bind(const std::string& ip, int port) { sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ip.c_str()); addr.sin_port = htons(port); int ret = ::bind(m_sockfd, (sockaddr*)&addr, sizeof(addr)); if (ret == -1) { return false; } return true; } bool listen(int backlog) { int ret = ::listen(m_sockfd, backlog); if (ret == -1) { return false; } return true; } bool connect(const std::string& ip, int port) { sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ip.c_str()); addr.sin_port = htons(port); int ret = ::connect(m_sockfd, (sockaddr*)&addr, sizeof(addr)); if (ret == -1) { return false; } return true; } bool accept(TcpSocket& clientSock) { sockaddr_in addr; socklen_t len = sizeof(addr); int clientfd = ::accept(m_sockfd, (sockaddr*)&addr, &len); if (clientfd == -1) { return false; } clientSock.setSockfd(clientfd); clientSock.setAddr(addr); return true; } bool send(const std::string& data) { int ret = ::send(m_sockfd, data.c_str(), data.size(), 0); if (ret == -1) { return false; } return true; } bool recv(std::string& data) { char buf[1024] = {0}; int ret = ::recv(m_sockfd, buf, 1024, 0); if (ret == -1) { return false; } else if (ret == 0) { return false; } data = buf; return true; } void close() { if (m_sockfd != -1) { ::close(m_sockfd); m_sockfd = -1; } } int getSockfd() const { return m_sockfd; } void setSockfd(int sockfd) { m_sockfd = sockfd; } void setAddr(const sockaddr_in& addr) { m_addr = addr; } std::string getPeerIp() const { return inet_ntoa(m_addr.sin_addr); } int getPeerPort() const { return ntohs(m_addr.sin_port); } private: int m_sockfd; sockaddr_in m_addr; }; int main() { TcpSocket serverSock; if (!serverSock.create()) { std::cout << "create socket failed!" << std::endl; return -1; } if (!serverSock.bind("0.0.0.0", 8888)) { std::cout << "bind socket failed!" << std::endl; return -1; } if (!serverSock.listen(5)) { std::cout << "listen socket failed!" << std::endl; return -1; } while (1) { TcpSocket clientSock; if (!serverSock.accept(clientSock)) { std::cout << "accept socket failed!" << std::endl; continue; } std::cout << "client ip: " << clientSock.getPeerIp() << ", port: " << clientSock.getPeerPort() << std::endl; std::string data; if (!clientSock.recv(data)) { std::cout << "recv data failed!" << std::endl; continue; } std::cout << "recv data: " << data << std::endl; if (!clientSock.send("hello client!")) { std::cout << "send data failed!" << std::endl; continue; } } return 0; } ``` 这个例子中,TcpSocket类封装了一些常用的TCP socket操作,包括创建socket、绑定端口、监听端口、连接远程主机、接收连接、发送数据和接收数据等。可以根据需求进行扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值