当前位置:首页 > 行业动态 > 正文

c 获取域名 端口号

获取域名和端口号通常需要使用网络编程接口或特定的库函数,具体方法取决于编程语言和环境。

在C语言中,获取域名和端口号是网络编程中的常见需求,以下是一些详细的方法介绍:

1、获取本地端口号

使用getsockname函数

该函数用于获取与指定套接字关联的本地地址,其原型为int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

示例代码如下:

 #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <unistd.h>
        #include <arpa/inet.h>
        #include <sys/socket.h>
        int main() {
            int server_fd;
            struct sockaddr_in address;
            int addrlen = sizeof(address);
            if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
                perror("socket failed");
                exit(EXIT_FAILURE);
            }
            address.sin_family = AF_INET;
            address.sin_addr.s_addr = INADDR_ANY;
            address.sin_port = htons(0); // 让系统自动分配端口
            if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
                perror("bind failed");
                close(server_fd);
                exit(EXIT_FAILURE);
            }
            // 获取本地地址
            if (getsockname(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen) == -1) {
                perror("getsockname failed");
                close(server_fd);
                exit(EXIT_FAILURE);
            }
            printf("Local port: %d
", ntohs(address.sin_port));
            return 0;
        }

在这个示例中,首先创建了一个套接字并绑定到一个任意端口(通过将sin_port设置为0),使用getsockname函数获取绑定的端口号,并通过ntohs函数将其转换为主机字节序进行打印。

c 获取域名 端口号

2、获取远端端口号

使用getpeername函数

此函数用于获取与指定套接字关联的远端地址,其原型为int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

示例代码如下:

c 获取域名 端口号

 #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <unistd.h>
        #include <arpa/inet.h>
        #include <sys/socket.h>
        #define PORT 8080
        int main() {
            int server_fd, new_socket;
            struct sockaddr_in address, client_addr;
            int addrlen = sizeof(address);
            int client_addrlen = sizeof(client_addr);
            // 创建套接字
            if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
                perror("socket failed");
                exit(EXIT_FAILURE);
            }
            // 设置地址和端口
            address.sin_family = AF_INET;
            address.sin_addr.s_addr = INADDR_ANY;
            address.sin_port = htons(PORT);
            // 绑定套接字
            if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
                perror("bind failed");
                close(server_fd);
                exit(EXIT_FAILURE);
            }
            // 监听套接字
            if (listen(server_fd, 3) < 0) {
                perror("listen");
                close(server_fd);
                exit(EXIT_FAILURE);
            }
            // 接受客户端连接
            if ((new_socket = accept(server_fd, (struct sockaddr *)&client_addr, (socklen_t*)&client_addrlen))<0) {
                perror("accept");
                close(server_fd);
                exit(EXIT_FAILURE);
            }
            // 获取远端地址
            if (getpeername(new_socket, (struct sockaddr *)&client_addr, (socklen_t*)&client_addrlen) == -1) {
                perror("getpeername failed");
                close(new_socket);
                close(server_fd);
                exit(EXIT_FAILURE);
            }
            printf("Remote port: %d
", ntohs(client_addr.sin_port));
            close(new_socket);
            close(server_fd);
            return 0;
        }

上述代码中,服务器先创建一个套接字并绑定到指定端口,然后开始监听,当有客户端连接时,使用accept函数接受连接,并通过getpeername函数获取客户端的远端端口号。

3、获取域名对应的IP地址及端口号(如果已知服务类型)

使用getaddrinfo函数

getaddrinfo函数是POSIX标准的一部分,它提供了一种独立于协议的方式来解析主机名和服务名,其原型为int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);,其中node是要解析的主机名或IP地址字符串,service是服务名或端口号字符串,hints是一个可选的addrinfo结构体,用于提供输入数据,res是一个指向addrinfo结构体链表的指针,用于输出结果。

c 获取域名 端口号

示例代码如下:

 #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <netdb.h>
        #include <arpa/inet.h>
        int main() {
            struct addrinfo hints, *res;
            int status;
            memset(&hints, 0, sizeof hints);
            hints.ai_family = AF_UNSPEC; // 允许IPv4或IPv6
            hints.ai_socktype = SOCK_STREAM; // TCP流
            status = getaddrinfo("www.example.com", "http", &hints, &res);
            if (status != 0) {
                fprintf(stderr, "getaddrinfo error: %s
", gai_strerror(status));
                return 1;
            }
            for (struct addrinfo *p = res; p != NULL; p = p->ai_next) {
                void *addr;
                char *ipver;
                char ipstr[INET6_ADDRSTRLEN];
                if (p->ai_family == AF_INET) { // IPv4
                    struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
                    addr = &(ipv4->sin_addr);
                    ipver = "IPv4";
                } else { // IPv6
                    struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
                    addr = &(ipv6->sin6_addr);
                    ipver = "IPv6";
                }
                // 将地址转换为字符串形式
                inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
                printf("%s: %s
", ipver, ipstr);
            }
            freeaddrinfo(res); // 释放内存
            return 0;
        }

在这个例子中,通过调用getaddrinfo函数解析域名www.example.com的IP地址,并根据服务名http确定端口号(HTTP默认端口为80),然后遍历返回的addrinfo结构体链表,提取并打印IP地址信息,如果是其他服务,可以将service参数修改为相应的服务名或端口号字符串。

在C语言中获取域名和端口号需要根据具体的需求和场景选择合适的方法,无论是获取本地端口号、远端端口号还是通过域名获取IP地址及端口号,都需要正确使用相关的系统调用和库函数,并进行适当的错误处理,以确保程序的稳定性和可靠性。