C/C++ socket編程(1)

C/C++ socket編程(1)

1.主機名到IP地址的映射。

IPv4中使用gethostbyname()函數完成主機名到地址解析,這個函數僅僅支持IPv4,且不允許調用者指定所需地址類型的任何信息,返回的結構只包含了用於存儲IPv4地址的空間。
例子:
bool MY_getHostbyName(char * const hostname)
{
    struct hostent *hptr;
    if((hptr = gethostbyname(hostname)) == NULL)
    {
        printf("[ERROR] can not analyze hostname : \t%s\n", hostname);
        return false;
    }
    printf("official hostname : \t%s\n", hptr->h_name);


    char **pptr;
    char str[32] = {0};
    for(pptr = hptr->h_aliases; *pptr != NULL; pptr++)
        printf(" alias:%s\n",*pptr);


    switch(hptr->h_addrtype)
    {
    case AF_INET:
        for(pptr = hptr->h_addr_list; *pptr != NULL; pptr++)
        {
            inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str));
            printf("address : \t\t%s\n", str);
        }
        inet_ntop(hptr->h_addrtype, hptr->h_addr, str, sizeof(str));
        printf("first address : \t%s\n", str);
        break;
    default:
        printf("unknown address type\n");
        break;
    }
    return true;
}



2.socket 與 IP地址的映射

使用下面2個函數getsockname(),getpeername()。


#include<sys/socket.h>
///getsockname函數用於獲取與某個套接字關聯的本地協議地址。
int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);

///getpeername函數用於獲取與某個套接字關聯的外地協議地址。
int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);


對於這兩個函數,如果函數調用成功,則返回0,如果調用出錯,則返回-1。
使用這兩個函數,我們可以通過套接字描述符來獲取自己的IP地址和連接對端的IP地址。


TCP
  對於服務器來說,在bind以後就可以調用getsockname來獲取本地地址和端口,雖然這沒有什麼太多的意義。getpeername只有在鏈接建立以後才調用,否則不能正確獲得對方地址和端口,所以他的參數描述字一般是鏈接描述字而非監聽套接口描述字。
  對於客戶端來說,在調用socket時候內核還不會分配IP和端口,此時調用getsockname不會獲得正確的端口和地址(當然鏈接沒建立更不可能調用getpeername),當然如果調用了bind 以後可以使用getsockname。想要正確的到對方地址(一般客戶端不需要這個功能),則必須在鏈接建立以後,同樣鏈接建立以後,此時客戶端地址和端口就已經被指定,此時是調用getsockname的時機。

/// getpeername 例子, getsocketname類似。
struct sockaddr_in tmp_addr;
socklen_t sock_len = sizeof(struct sockaddr_in);
getpeername(fd_socket, (struct sockaddr *)&tmp_addr, &sock_len);
printf("\n[Info] Close socket : %d : %s, \"%s:%d\".\n",
           fd_socket, reason,
           (char *)inet_ntoa(tmp_addr.sin_addr), tmp_addr.sin_port);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章