http服务器代码里哪里体现TCP三次握手

0、TCP三次握手状态图

在这里插入图片描述

1. 创建套接字

SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);

这里使用 socket 函数创建了一个基于 IPv4(AF_INET)的流式套接字(SOCK_STREAM),流式套接字默认使用 TCP 协议,这是三次握手的基础,因为三次握手是 TCP 协议建立连接的过程。

2. 绑定地址和监听

sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(8080);

if (bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
    // 错误处理
}
if (listen(serverSocket, 5) == SOCKET_ERROR) {
    // 错误处理
}
  • bind 函数将创建的套接字与指定的 IP 地址和端口(这里是 8080)绑定,使得服务器可以在该地址和端口上监听客户端的连接请求。
  • listen 函数将套接字设置为监听状态,允许客户端发起连接请求。此时服务器已经准备好进行三次握手来接受客户端的连接。

3. 接受连接

SOCKET clientSocket = accept(serverSocket, (sockaddr*)&clientAddr, &clientAddrLen);

accept 函数是三次握手完成的关键触发点。当客户端发起连接请求时,会向服务器发送 SYN 包,服务器接收到这个 SYN 包后,操作系统内核会自动处理三次握手的后续步骤:

  • 服务器内核会向客户端发送 SYN + ACK 包作为响应。
  • 客户端收到 SYN + ACK 包后,会再发送 ACK 包给服务器。
  • 当三次握手完成后,accept 函数才会返回一个新的套接字 clientSocket,用于与客户端进行后续的数据通信。

总结来说,在代码里三次握手的具体实现是由操作系统内核完成的,代码中通过 socketbindlistenaccept 这些函数间接触发和利用了操作系统的三次握手机制,以建立可靠的 TCP 连接用于后续的 HTTP 通信。

4、附代码

#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>

// 引入静态链接库
#pragma comment(lib, "ws2_32.lib")

const int DEFAULT_PORT = 8889;

// 处理GET请求的函数,这里简单返回固定内容示例
std::string handleGetRequest(const std::string& request) {
    std::string response = "HTTP/1.1 200 OK\r\n";
    response += "Content-Type: text/html; charset=UTF-8\r\n";
    response += "\r\n";
    response += "<html><body><h1>Hello from GET!</h1></body></html>";
    return response;
}

// 处理POST请求的函数,这里简单返回固定内容示例,实际中可根据POST数据做处理
std::string handlePostRequest(const std::string& request) {
    std::string response = "HTTP/1.1 200 OK\r\n";
    response += "Content-Type: text/html; charset=UTF-8\r\n";
    response += "\r\n";
    response += "<html><body><h1>Hello from POST!</h1></body></html>";
    return response;
}

int main() {
    // 初始化WinSock
    WSADATA wsaData;
    int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (result != 0) {
        std::cerr << "WSAStartup failed: " << result << std::endl;
        return 1;
    }

    // 创建套接字
    SOCKET listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (listenSocket == INVALID_SOCKET) {
        std::cerr << "Socket creation failed: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    // 绑定地址和端口
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    serverAddr.sin_port = htons(DEFAULT_PORT);
    result = bind(listenSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
    if (result == SOCKET_ERROR) {
        std::cerr << "Bind failed: " << WSAGetLastError() << std::endl;
        closesocket(listenSocket);
        WSACleanup();
        return 1;
    }

    // 监听端口
    result = listen(listenSocket, SOMAXCONN);
    if (result == SOCKET_ERROR) {
        std::cerr << "Listen failed: " << WSAGetLastError() << std::endl;
        closesocket(listenSocket);
        WSACleanup();
        return 1;
    }

    std::cout << "Server is listening on port " << DEFAULT_PORT << std::endl;

    while (true) {
        // 接受客户端连接
        SOCKET clientSocket = accept(listenSocket, NULL, NULL);
        if (clientSocket == INVALID_SOCKET) {
            std::cerr << "Accept failed: " << WSAGetLastError() << std::endl;
            continue;
        }

        char buffer[1024];
        int bytesReceived = recv(clientSocket, buffer, sizeof(buffer), 0);
        if (bytesReceived > 0) {
            buffer[bytesReceived] = '\0';
            std::string request(buffer);
            std::string response;

            // 判断请求方法是GET还是POST
            if (request.find("GET") == 0) {
                response = handleGetRequest(request);
                std::cout << request <<std:: endl;
            }
            else if (request.find("POST") == 0) {
                response = handlePostRequest(request);
            }
            else {
                // 对于不支持的方法返回405 Method Not Allowed
                response = "HTTP/1.1 405 Method Not Allowed\r\n";
                response += "Content-Type: text/html; charset=UTF-8\r\n";
                response += "\r\n";
                response += "<html><body><h1>405 Method Not Allowed</h1></body></html>";
            }

            // 发送响应给客户端
            send(clientSocket, response.c_str(), response.length(), 0);
        }

        // 关闭客户端套接字
        closesocket(clientSocket);
    }

    // 关闭监听套接字,清理WinSock环境
    closesocket(listenSocket);
    WSACleanup();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值