2012-10-10 40 views
7

Tôi hiện đang làm việc trên máy chủ UDP nhận yêu cầu từ khách hàng. Datagram tôi nhận được là một mảng (char) mảng dài 5 phần tử, với hai phần tử cuối cùng là một số cổng.Trích xuất địa chỉ IP và thông tin cổng từ sockaddr_storage

Cuối cùng, máy chủ này sẽ phải trả lại cả địa chỉ IP và số cổng trong một gói dữ liệu của riêng nó.

Tôi đã biết cách sử dụng inet_ntop và cấu trúc sockaddr mà tôi đã kết nối và nhận được từ để in ra ip, nhưng nó trả về một chuỗi không có định dạng tôi muốn. Ví dụ:

string1 = inet_ntop(their_addr.ss_family,get_in_addr(
    (struct sockaddr *)&their_addr),s, sizeof s); 

lợi nhuận:

127.0.0.1 

hay:

[1][2][7][.][0][.][0][.][1] 

khi tôi cần một cái gì đó như:

[127][0][0][1] 

Tôi có nên sử dụng một số loại nhân vật và thao tác mảng để tạo thành phần tử 4 phần tử của tôi e mảng? Hay một sockaddr có thông tin này theo cách mà tôi có thể để nó ở dạng hex và trả lại nó?

Trả lời

12

Giả sử cho IPv4.

Sau khi lấy địa chỉ của cấu trúc sockaddr_storage hoặc sockaddr và truyền nó đến phiên bản IPv4 sockaddr_in, bạn có thể truy cập từng byte riêng lẻ của địa chỉ IPv4.

struct sockaddr_in *sin = (struct sockaddr_in *)&their_addr; 

Sau đó, bạn có thể tận địa chỉ của s_addr thành viên đó là một giá trị 32 bit (in_addr_t) chứa 4 byte của địa chỉ ip (theo thứ tự byte mạng) và bỏ nó vào một con trỏ đến một unsigned char mà sau đó cho phép bạn truy cập các byte riêng lẻ của giá trị.

unsigned char *ip = (unsigned char *)&sin->sin_addr.s_addr; 

printf("%d %d %d %d\n", ip[0], ip[1], ip[2], ip[3]); 
+0

Đây là chính xác những gì tôi đang tìm kiếm. Ngắn gọn và tuyệt vời. Cảm ơn @Kludas – Ryanman

5

Bạn muốn có thể sử dụng chức năng getnameinfo():

int getnameinfo(const struct sockaddr *sa, socklen_t salen, 
        char *host, size_t hostlen, 
        char *serv, size_t servlen, int flags); 

ví dụ .:

struct sockaddr_storage client_addr; 
socklen_t client_len = sizeof(struct sockaddr_storage); 

/* Accept client request */ 
int client_socket = accept(server_socket, 
    (struct sockaddr *)&client_addr, &client_len); 

char hoststr[NI_MAXHOST]; 
char portstr[NI_MAXSERV]; 

int rc = getnameinfo((struct sockaddr *)&client_addr, 
    client_len, hoststr, sizeof(hoststr), portstr, sizeof(portstr), 
    NI_NUMERICHOST | NI_NUMERICSERV); 

if (rc == 0) 
    printf("New connection from %s %s", hoststr, portstr); 
Các vấn đề liên quan