TCP常见问题详解

简介: TCP常见问题详解

本篇文章我们介绍一下 在我们的面试中和实际开发中使用TCP遇到的问题

1.TCP在什么情况下出现大量的time_event

什么是time_event?

我们首先要弄清楚TIME_WAIT状态是什么?TIME_WAIT状态是主动关闭TCP连接的一方(即先发起FIN包的一方),在发送完最后一个ACK包后进入的状态。系统需要在TIME_WAIT状态下等待2MSL(maximum segment lifetime )后才能释放连接(端口)。根据RFC 793 MSL是2分钟,一般的TCP实现有30秒、1分钟和2分钟不等。进入TIME_WAIT状态等待2MSL主要有两个目的:一方面是主动关闭连接的一方在对方没有收到最后一个ACK包时(这时对方还会重发FIN,收到两个FIN的时间间隔一定小于2MSL)有时间可以重发ACK包,另一方面处于TIME_WAIT的连接(IP和端口组合)不能重用,这样可以保证被重新分配的socket不会受到之前残留的延迟重发报文影响。

由于主动关闭TCP连接的一方才会进入TIME_WAIT状态,一般情况服务器端不会出现TIME_WAIT状态,因为大多数情况都是客户端主动发起连接并主动关闭连接。但是某些服务如pop/smtp、ftp却是服务端收到客户端的QUIT命令后主动关闭连接,这就造成这类服务器上容易出现大量的TIME_WAIT状态的连接,而且并发量越大处于此种状态的连接越多。另外,对于被动关闭连接的服务在主动关闭客户端非法请求或清理长时间不活动的连接时(这种情况很可能是客户端程序忘记关闭连接)也会出现TIME_WAIT的状态。

2.TCP粘包解决的办法

黏包问题是指在传输过程中多个数据包被合并成了一个或者一个数据包被拆分成了多个,造成接收方无法正确解析。解决黏包问题的方法主要有以下两种:

  1. 固定包头接收:发送方在每个数据包前加上固定长度的头部信息,接收方先读取头部信息获取数据包长度,再根据长度截取对应的数据。这样可以保证每次接收到的数据都是完整的。
  2. 指定内存长度:发送方在每个数据包前不添加任何头部信息,而是在尾部添加一个特殊字符(例如换行符“\n”),接收方按照特殊字符进行切割,并且预先给缓存区分配足够长的空间来容纳整个消息。这样也能确保接收到的数据都是完整的。

解决TCP粘包的代码实例:

核心思想:在C++中,处理TCP粘包问题通常涉及到自定义协议来区分数据包。这意味着需要设计一种机制来标记每个数据包的开始和结束。

服务器端:

#include <boost/asio.hpp>  
#include <iostream>  
#include <vector>  
  
using boost::asio::ip::tcp;  
  
class session : public std::enable_shared_from_this<session> {  
public:  
    session(tcp::socket socket) : socket_(std::move(socket)) {}  
  
    void start() {  
        do_read();  
    }  
  
private:  
    void do_read() {  
        auto self(shared_from_this());  
        char buffer[1024];  
  
        socket_.async_read_some(boost::asio::buffer(buffer),  
            [this, self](boost::system::error_code ec, std::size_t length) {  
                if (!ec) {  
                    std::cout.write(buffer, length);  
                    std::cout << std::endl;  
  
                    do_read();  
                }  
            });  
    }  
  
    tcp::socket socket_;  
};  
  
int main(int argc, char* argv[]) {  
    try {  
        if (argc != 2) {  
            std::cerr << "Usage: async_tcp_echo_server <port>\n";  
            return 1;  
        }  
  
        boost::asio::io_context io_context;  
  
        tcp::acceptor acceptor(io_context, tcp::endpoint(tcp::v4(), std::atoi(argv[1])));  
  
        for (;;) {  
            tcp::socket socket(io_context);  
            acceptor.async_accept(socket,  
                [&](boost::system::error_code ec) {  
                    if (!ec) {  
                        std::make_shared<session>(std::move(socket))->start();  
                    }  
                });  
        }  
  
        io_context.run();  
    }  
    catch (std::exception& e) {  
        std::cerr << "Exception: " << e.what() << "\n";  
    }  
  
    return 0;  
}

客户端代码:

#include <boost/asio.hpp>  
#include <iostream>  
  
using boost::asio::ip::tcp;  
  
int main(int argc, char* argv[]) {  
    try {  
        if (argc != 3) {  
            std::cerr << "Usage: async_tcp_echo_client <host> <port>\n";  
            return 1;  
        }  
  
        boost::asio::io_context io_context;  
  
        tcp::resolver resolver(io_context);  
        tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);  
  
        tcp::socket socket(io_context);  
        boost::asio::connect(socket, endpoints);  
  
        for (int i = 0; i < 5; ++i) {  
            std::string message = "Hello, world! (" + std::to_string(i) + ")\n";  
  
            boost::asio::write(socket, boost::asio::buffer(message));  
        }  
  
        io_context.run();  
    }  
    catch (std::exception& e) {  
        std::cerr << "Exception: " << e.what() << "\n";  
    }  
  
    return 0;  
}

总结:本篇文章描述了C++的常见的一些问题  粘包 时间等待线程  这些在我们的开发中有时候会遇到 我们要积极的解决 否则就会出现很多问题

好了 本篇文章就到这里结束了 在这里我给大家推荐一个性价比很高的课程:

https://xxetb.xetslk.com/s/2PjJ3T

相关文章
|
2月前
|
网络协议
TCP连接释放过程
【8月更文挑战第20天】
34 3
|
5月前
|
网络协议 算法 Linux
TCP教程:详解TCP连接过程
TCP教程:详解TCP连接过程
657 0
|
5月前
|
网络协议 前端开发 JavaScript
TCP与UDP的区别:深入探索与应用案例
TCP与UDP的区别:深入探索与应用案例
50 2
|
缓存 网络协议 算法
【网络基础】TCP协议之三次握手&四次挥手--详解与常见问题解答(下)
【网络基础】TCP协议之三次握手&四次挥手--详解与常见问题解答(下)
|
网络协议 安全 网络安全
【网络基础】TCP协议之三次握手&四次挥手--详解与常见问题解答(上)
【网络基础】TCP协议之三次握手&四次挥手--详解与常见问题解答(上)
|
编解码 网络协议 算法
TCP 拥塞控制详解 | 1. 概述
TCP 拥塞控制详解 | 1. 概述
424 0
TCP 拥塞控制详解 | 1. 概述
|
网络协议 安全 网络架构
Tcp 客户端 | 学习笔记
快速学习 Tcp 客户端
213 0
Tcp 客户端 | 学习笔记
|
网络协议 开发者 Python
Tcp 服务器 | 学习笔记
快速学习 Tcp 服务器
385 0
|
网络协议 网络性能优化 网络架构
|
移动开发 网络协议 架构师
超详细的TCP、Sokcket和SuperSocket与TCP入门指导
本文主要介绍TCP、Sokcket和SuperSocket的基础使用。
超详细的TCP、Sokcket和SuperSocket与TCP入门指导