ZBLOG

c++实现支持ipv4和ipv6d协议的服务端,客户端可以是ipv4地址,也可以是ipv6地址

要实现支持IPv4和IPv6协议的服务端,可以使用socket编程来完成。以下是一个简单的C++代码示例:

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 8080

int main(int argc, char *argv[]) {
    int server_fd, new_socket;
    struct sockaddr_in6 address;
    int opt = 1;
    int addrlen = sizeof(address);
    
    // 创建socket
    if ((server_fd = socket(AF_INET6, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }
    
    // 设置socket选项,允许地址重用
    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
            &opt, sizeof(opt))) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }
    
    // 设置地址族为IPv6
    address.sin6_family = AF_INET6;
    
    // 设置监听的端口号
    address.sin6_port = htons(PORT);
    
    // 将IP地址设置为任意地址
    address.sin6_addr = in6addr_any;
    
     // 绑定到指定的IP地址和端口上
     if (bind(server_fd, (struct sockaddr *)&address,
          sizeof(address))<0) {
         perror("bind failed");
         exit(EXIT_FAILURE);
     }

     // 开始监听客户端连接请求
     if (listen(server_fd, 3) < 0) {
         perror("listen");
         exit(EXIT_FAILURE);
     }

     std::cout << "Server started and listening on port " << PORT << std::endl;

     while (true) {
         // 接受客户端连接请求
         if ((new_socket = accept(server_fd, (struct sockaddr *)&address,
                 (socklen_t*)&addrlen))<0) {
             perror("accept");
             exit(EXIT_FAILURE);
         }

         // 打印客户端的地址信息
         char ip[INET6_ADDRSTRLEN];
         inet_ntop(AF_INET6, &address.sin6_addr, ip, INET6_ADDRSTRLEN);
         std::cout << "New client connected from " << ip << std::endl;
         
        // TODO: 处理客户端请求
     }
     
     return 0;
}

在客户端连接时,可以使用getaddrinfo()函数来自动判断是IPv4还是IPv6地址。以下是一个简单的C++代码示例:

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define PORT 8080

int main(int argc, char *argv[]) {
    int sock = 0;
    struct sockaddr_in6 serv_addr;
    
    // 解析主机名和服务名,获取对应的IP地址和端口号列表
    struct addrinfo hints{};
    hints.ai_family = AF_UNSPEC; // 支持IPv4和IPv6
    hints.ai_socktype = SOCK_STREAM; // 使用TCP协议
    
    struct addrinfo *result;
    if (getaddrinfo(argv[1], argv[2], &hints, &result) != 0) {
        perror("getaddrinfo");
        exit(EXIT_FAILURE);
    }
    
    // 尝试连接到服务器,直到成功或出错为止
    for (struct addrinfo *rp = result; rp != nullptr; rp = rp->ai_next) {
        sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if (sock == -1) {
            continue;
        }
        
        if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1) {
            break;
        }
        
        close(sock);
    }

    // 如果连接失败,则输出错误信息并退出
    if (sock == -1) {
        perror("connect");
        exit(EXIT_FAILURE);
    }
    
    // 打印连接成功的服务器地址信息
    char ip[INET6_ADDRSTRLEN];
    inet_ntop(serv_addr.sin6_family, &serv_addr.sin6_addr, ip, INET6_ADDRSTRLEN);
    std::cout << "Connected to " << ip << ":" << ntohs(serv_addr.sin6_port)
              << std::endl;
              
    // TODO: 发送和接收数据
    
    return 0;
}

以上代码示例只是一个简单的演示,实际上在处理客户端请求时还需要进行更多的工作。例如,可以使用select()函数来实现非阻塞IO,使用线程或者进程来处理多个客户端请求等等。


内容由零声教学AI助手提供,问题来源于学员提问

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://sdn.0voice.com/?id=1579

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?