问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

TCP通信机制详解:三次握手、四次挥手与滑动窗口

创作时间:
作者:
@小白创作中心

TCP通信机制详解:三次握手、四次挥手与滑动窗口

引用
1
来源
1.
https://cloud.tencent.com.cn/developer/article/2474272

TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。它通过三次握手建立连接,通过四次挥手断开连接,并使用滑动窗口机制进行流量控制。本文将详细介绍TCP的三次握手、四次挥手以及滑动窗口机制,并通过C语言代码实现server和client的通信过程。

1. TCP三次握手

TCP在建立连接时需要进行三次握手,确保双方都能正确接收和发送数据。

  • 第一次握手:客户端发送SYN标志位,附带一个随机序号(例如100),可以携带数据(例如10字节)。

  • 第二次握手:服务端收到SYN后,发送ACK确认序号(客户端序号+1)和自己的SYN请求。

  • 第三次握手:客户端收到服务端的ACK后,发送最终的ACK确认,完成连接建立。

2. TCP四次挥手

断开连接时需要进行四次挥手,确保双方都能正确关闭连接。

  • 第一次挥手:任意一端发送FIN标志位,附带序号。

  • 第二次挥手:另一端发送ACK确认。

  • 第三次挥手:另一端发送FIN标志位。

  • 第四次挥手:第一端发送ACK确认,完成连接关闭。

3. TCP连接与数据传输过程

TCP连接的完整过程包括三次握手、数据传输和四次挥手。在数据传输阶段,双方会通过ACK确认数据接收情况。

4. TCP滑动窗口机制

滑动窗口机制用于流量控制,确保发送方不会发送过多数据导致接收方缓冲区溢出。

  • 发送端速度快,接收端速度慢:发送端会根据接收端的滑动窗口大小发送数据,当接收端处理完部分数据后,会更新窗口大小并通知发送端。

  • 重传机制:如果数据传输失败,TCP会进行重传,确保数据的可靠传输。

5. server服务端与client客户端编程实现

以下是server和client的C语言代码实现:

server.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <ctype.h>

int main(int argc, char* argv[]) {
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd == -1) {
        perror("socket err");
        exit(1);
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(8765);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    int ret = bind(lfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    if(ret == -1) {
        perror("bind err");
        exit(1);
    }

    ret = listen(lfd, 128);
    if(ret == -1) {
        perror("listen err");
        exit(1);
    }

    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    int cfd = accept(lfd, (struct sockaddr*)&client_addr, &client_len);
    if(cfd == -1) {
        perror("accept err");
        exit(1);
    }

    char ipbuf[64];
    printf("client ip: %s, port: %d\n",
           inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, ipbuf, sizeof(ipbuf)),
           ntohs(client_addr.sin_port));

    while(1) {
        char buf[1024] = {0};
        int len = read(cfd, buf, sizeof(buf));
        if(len < 0) {
            perror("read err");
            break;
        } else if(len == 0) {
            printf("client disconnect ...\n");
            break;
        } else {
            printf("read buf : %s\n", buf);
            for(int i = 0; i < len; i++) {
                buf[i] = toupper(buf[i]);
            }
            printf("toupper read buf: %s\n", buf);
            write(cfd, buf, strlen(buf) + 1);
        }
    }
    close(lfd);
    close(cfd);
    return 0;
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <arpa/inet.h>
#include <fcntl.h>

int main(int argc, char* argv[]) {
    if(argc < 2) {
        printf("err:./exe port\n");
        return -1;
    }
    int port = atoi(argv[1]);

    int fd = socket(AF_INET, SOCK_STREAM, 0);
    if(fd == -1) {
        perror("socket err");
        exit(1);
    }

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr.s_addr);

    int ret = connect(fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    if(ret == -1) {
        perror("connect err");
        exit(1);
    }

    while(1) {
        char buf[512];
        printf("please input string: \n");
        fgets(buf, sizeof(buf), stdin);
        write(fd, buf, strlen(buf));

        int len = read(fd, buf, sizeof(buf));
        if(len < 0) {
            perror("read err");
            exit(1);
        } else if(len == 0) {
            printf("server close connect ...\n");
            break;
        } else {
            printf("read buf: %s, buflen: %d\n", buf, len);
        }
    }
    close(fd);
    return 0;
}

本文详细介绍了TCP通信机制的核心内容,包括三次握手、四次挥手和滑动窗口机制,并通过代码示例帮助读者理解TCP通信的实现过程。对于从事网络通信相关工作的技术人员来说,本文具有较高的参考价值。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号