📜  c++ 绑定端口 - C++ (1)

📅  最后修改于: 2023-12-03 14:59:49.570000             🧑  作者: Mango

C++ 绑定端口

在 C++ 中,要实现网络编程需要绑定端口。

绑定端口的方法
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

const int PORT = 8080;

int main() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建 socket
    if (sockfd < 0) {
        cerr << "Error: Failed to create socket." << endl;
        exit(1);
    }

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

    if (bind(sockfd, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) { // 绑定 IP 和端口
        cerr << "Error: Failed to bind socket." << endl;
        exit(1);
    }

    listen(sockfd, 10); // 监听端口

    cout << "Server is running on port " << PORT << "." << endl;

    while (true) {
        struct sockaddr_in client_address;
        socklen_t client_addrlength = sizeof(client_address);
        int connfd = accept(sockfd, (struct sockaddr *)&client_address, &client_addrlength); // 接收客户端连接
        if (connfd < 0) {
            cerr << "Error: Failed to accept client connection." << endl;
            continue;
        }

        cout << "New client " << inet_ntoa(client_address.sin_addr) << ":" << ntohs(client_address.sin_port) << " is connected." << endl;

        // 处理客户端请求

        close(connfd); // 关闭连接
    }
    close(sockfd);
    return 0;
}
代码解析

首先,我们创建了一个 socket,即 int sockfd = socket(AF_INET, SOCK_STREAM, 0);,其中:

  • AF_INET 表示 IP 地址族。
  • SOCK_STREAM 表示传输层协议为面向连接的 TCP 协议。
  • 0 表示默认协议。

接下来,我们需要初始化服务器地址结构体 struct sockaddr_in,即:

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

其中:

  • memset 用来将结构体清零。
  • htonlhtons 用来将主机字节序转换为网络字节序。
  • INADDR_ANY 表示任意 IP 地址。

然后,我们调用 bind 函数来将 IP 和端口绑定到 socket 上,即 bind(sockfd, (struct sockaddr *)&server_address, sizeof(server_address))

接着,我们调用 listen 函数来监听端口,即 listen(sockfd, 10),其中 10 表示同时连接的客户端数量限制。

最后,我们进入死循环,等待客户端连接。当客户端连接成功时,我们调用 accept 函数来接收客户端连接,即 int connfd = accept(sockfd, (struct sockaddr *)&client_address, &client_addrlength),其中 connfd 表示连接描述符,即客户端套接字,client_address 存放客户端信息的结构体,client_addrlength 表示传入的 client_address 结构体的长度指针。

当客户端请求处理完毕后,我们调用 close(connfd) 关闭连接。

总结

绑定端口是网络编程中必不可少的一步。我们需要调用 socket 创建 socket,调用 bind 绑定端口,调用 listen 监听端口,然后进入死循环等待客户端连接,接收客户端连接后,处理客户端请求,处理完毕后关闭连接。