2010-03-22 69 views
3

我正在準備一個簡單的工作項目,並試圖熟悉Unix開發環境中的套接字編程的基礎知識。在這一點上,我有一些基本的服務器端代碼設置爲監聽來自客戶端的TCP連接請求的母套接字已創建並設置爲偵聽後...如何獲取客戶端的IPv4地址?

int sockfd, newfd;  
unsigned int len; 
socklen_t sin_size; 
char msg[]="Test message sent"; 
char buf[MAXLEN]; 
int st, rv; 
struct addrinfo hints, *serverinfo, *p; 
struct sockaddr_storage client; 
char ip[INET6_ADDRSTRLEN]; 

. 
. //parent socket creation and listen code omitted for simplicity 
. 

//wait for connection requests from clients 
while(1) 
    { 
    //Returns the socketID and address of client connecting to socket 
    if((newfd = accept(sockfd, (struct sockaddr *)&client, &len)) == -1){ 
     perror("Accept"); 
     exit(-1); 
    } 

    if((rv = recv(newfd, buf, MAXLEN-1, 0)) == -1) { 
     perror("Recv"); 
     exit(-1); 
    } 
    struct sockaddr_in *clientAddr = (struct sockaddr_in *) get_in_addr((struct sockaddr *)&client); 
    inet_ntop(client.ss_family, clientAddr, ip, sizeof ip); 
    printf("Receive from %s: query type is %s\n", ip, buf); 

    if((st = send(newfd, msg, strlen(msg), 0)) == -1) { 
     perror("Send"); 
     exit(-1); 
    } 

    //ntohs is used to avoid big-endian and little endian compatibility issues 
    printf("Send %d byte to port %d\n", ntohs(clientAddr->sin_port)); 

    close(newfd); 
    } 

} 

我在網上找到了get_in_addr功能把它放在我的代碼的頂部,並用它來獲得客戶端連接的IP地址...

// get sockaddr, IPv4 or IPv6: 
void *get_in_addr(struct sockaddr *sa) 
{ 
    if (sa->sa_family == AF_INET) { 
    return &(((struct sockaddr_in*)sa)->sin_addr); 
    } 

    return &(((struct sockaddr_in6*)sa)->sin6_addr); 
} 

但功能總是返回IPv6的IP地址,因爲什麼sa_family屬性設置爲多數民衆贊成。

我的問題是,IPv4 IP地址存儲在我正在使用的數據中的任何地方,如果有,我如何訪問它?

非常感謝您的幫助!

回答

4

如果您正在獲取IPv6地址,那麼客戶端正在使用這個地址進行連接。 IPv6和IPv4地址之間以及IP地址和客戶端設備之間不存在1-1對應關係。

它有點像說你收到了某人的電子郵件,但是你無法通過他們的電子郵件地址計算出他們的郵寄地址。

+0

我認爲可能是這種情況。感謝您的澄清,我真的很感激! – BeachRunnerFred 2010-03-22 15:51:48

0

當您在物理上獲取IPv6地址時,如果客戶端與IPv4連接,則地址將在IPv4-mapped address format中。

您可以通過訪問s6_addr的字節12,13,14和15來提取地址的IPv4部分。

相關問題