2010-01-14 33 views
16

Tôi có một máy chủ có ổ cắm đến từ một máy khách. Tôi cần có địa chỉ IP của ứng dụng khách từ xa. Đã thử tìm kiếm trên google in_addr nhưng hơi rắc rối một chút. Bất kỳ đề xuất nào?Lấy địa chỉ nguồn của một kết nối ổ cắm đến

+0

in_addr là IPv4-cụ thể, dù sao – bortzmeyer

+0

thấy (..) chức năng inet_ntoa trong linux .. 'người đàn ông inet_ntoa'. nó dễ dàng hơn inet_ntop theo ý kiến ​​của tôi và nhu cầu bao gồm arpa/inet.h. đây là một ví dụ: http://www.binarytides.com/programming-udp-sockets-c-linux/ – mhk

Trả lời

32

Bạn cần có chức năng getpeername. Hướng dẫn kết nối mạng lớn của Beej có số page about it. Dưới đây là một mẫu mã từ đó:

// assume s is a connected socket 

socklen_t len; 
struct sockaddr_storage addr; 
char ipstr[INET6_ADDRSTRLEN]; 
int port; 

len = sizeof addr; 
getpeername(s, (struct sockaddr*)&addr, &len); 

// deal with both IPv4 and IPv6: 
if (addr.ss_family == AF_INET) { 
    struct sockaddr_in *s = (struct sockaddr_in *)&addr; 
    port = ntohs(s->sin_port); 
    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); 
} else { // AF_INET6 
    struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; 
    port = ntohs(s->sin6_port); 
    inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); 
} 

printf("Peer IP address: %s\n", ipstr); 
+0

+1. Tuy nhiên, chúng ta không phải giải phóng bộ nhớ cho điều này? – iammilind

+1

Tôi nhận thấy 'struct sockaddr_in * s' đổ bóng' s' vào ổ cắm ngoài. Có một biến bóng không phải là lý tưởng. –

+0

là có cách để lấy socketDescriptor từ địa chỉ – Bionix1441

1

Vì bạn nói rằng nó là một kết nối đến từ một khách hàng, như một thay thế cho getpeername bạn chỉ có thể lưu các địa chỉ đó được trả về bởi các accept() cuộc gọi, trong lần thứ hai và thứ ba thông số.

9

Giả sử bạn đang sử dụng accept() để chấp nhận kết nối ổ cắm đến, getpeername() là không cần thiết. Thông tin địa chỉ có sẵn thông qua tham số thứ 2 và thứ 3 của cuộc gọi accept().

Dưới đây là câu trả lời của Eli sửa đổi để làm điều đó mà không getpeername():

int client_socket_fd; 
socklen_t len; 
struct sockaddr_storage addr; 
char ipstr[INET6_ADDRSTRLEN]; 
int port; 

len = sizeof addr; 
client_socket_fd = accept(server_socket_fd, (struct sockaddr*)&addr, &len); 

// deal with both IPv4 and IPv6: 
if (addr.ss_family == AF_INET) { 
    struct sockaddr_in *s = (struct sockaddr_in *)&addr; 
    port = ntohs(s->sin_port); 
    inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr); 
} else { // AF_INET6 
    struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr; 
    port = ntohs(s->sin6_port); 
    inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr); 
} 

printf("Peer IP address: %s\n", ipstr); 
+0

+1 để trực tiếp sử dụng 'accept()'. Tuy nhiên, chúng ta không phải giải phóng bộ nhớ cho điều này? – iammilind

+3

@iammilind: Tôi không nghĩ rằng bất kỳ bộ nhớ nào cần được giải phóng — Tôi không thể thấy bất kỳ phân bổ động nào đang được thực hiện. Tất cả được thực hiện với các biến được phân bổ tĩnh. –

Các vấn đề liên quan