socket
库来获取域名和端口号。以下是一个简单的示例:“ python,import sockethostname = 'www.example.com',port = 80# 创建一个socket对象,s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 获取主机名和端口号,host_info = socket.gethostbyname(hostname),print("Hostname:", hostname),print("IP Address:", host_info),print("Port:", port)# 关闭socket,s.close(),
` 在这个示例中,我们首先导入了
socket 库,然后创建了一个socket对象。我们使用
socket.gethostbyname()`函数获取了主机名对应的IP地址,并打印出了主机名、IP地址和端口号。我们关闭了socket对象。
在C语言中,获取域名和端口号通常涉及到网络编程的相关函数和数据结构,以下是一些常用的方法和步骤:
1、获取域名
www.example.com
对应的IP地址,可以使用以下代码:
“`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>
void print_address_info(const char hostname, const char service) {
struct addrinfo hints, res, p;
int status;
char ipstr[INET6_ADDRSTRLEN];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo(hostname, service, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo: %s
", gai_strerror(status));
return;
}
printf("IP addresses for %s:
", hostname);
for(p = res; p != NULL; p = p->ai_next) {
void addr;
char ipver;
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);
}
int main(int argc, char argv[]) {
if (argc != 3) {
fprintf(stderr, "usage: showip hostname service
");
return 1;
}
print_address_info(argv[1], argv[2]);
return 0;
}
:这是一个传统的网络地址解析函数,可以用于获取主机名对应的IP地址,不过需要注意的是,该函数已经被标记为过时,在新的代码中建议尽量使用 getaddrinfo
函数,示例代码如下: ```c #include <stdio.h> #include <stdlib.h> #include <netdb.h> #include <arpa/inet.h> void print_host_info(const char hostname) { struct hostent he; struct in_addr addr_list; if ((he = gethostbyname(hostname)) == NULL) { herror("gethostbyname"); return; } printf("IP addresses for %s: ", hostname); addr_list = (struct in_addr ) he->h_addr_list; for(; addr_list != NULL; addr_list++) { printf("%s ", inet_ntoa(addr_list)); } } int main(int argc, char argv[]) { if (argc != 2) { fprintf(stderr, "usage: showip hostname "); return 1; } print_host_info(argv[1]); return 0; }
2、获取端口号
从套接字地址结构体中获取:当使用套接字进行通信时,可以通过套接字地址结构体(如sockaddr_in
或sockaddr_in6
)来获取端口号,在服务器端接受客户端连接后,可以从客户端的套接字地址结构体中获取其端口号:
“`c
struct sockaddr_in clientAddr;
socklen_t sin_size = sizeof(clientAddr);
int new_fd = accept(sock, (struct sockaddr )&clientAddr, &sin_size);
if(new_fd<0) {
char msg[64];
bzero(msg,sizeof(msg));
sprintf(msg,"accept failed");
log::outputSysErr(msg);
} else {
// 将sockaddr强制转换为 sockaddr_in
sockaddr_in pSin = (sockaddr_in)&clientAddr;
int clientPort = ntohs(pSin->sin_port); // 将网络字节序转换为主机字节序
printf("Client port: %d
", clientPort);
}
:该函数用于获取与指定套接字关联的本地地址,包括端口号,在创建套接字并绑定端口后,可以使用 getsockname
函数获取绑定的端口号: ```c 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); } int localPort = ntohs(address.sin_port); // 将网络字节序转换为主机字节序 printf("Local port: %d ", localPort); close(server_fd);
使用getpeername
函数:该函数用于获取与指定套接字关联的远端地址,也包括端口号,通常在连接建立后,使用该函数获取客户端的端口号:
“`c
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);
}
listen(server_fd, 3);
new_socket = accept(server_fd, (struct sockaddr )&client_addr, (socklen_t)&client_addrlen);
if (new_socket < 0) {
perror("accept failed");
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);
}
int clientPort = ntohs(client_addr.sin_port); // 将网络字节序转换为主机字节序
printf("Client port: %d
", clientPort);
close(new_socket);
close(server_fd);
通过这些方法,可以在C语言中有效地获取域名和端口号,从而进行网络通信和相关操作。