一、gethostname,gethostbyname的用法

这两个函数可以用来获取主机的信息。
gethostname:获取主机的名字
gethostbyname:通过名字获取其他的信息(比如ip)

1.gethostname:
man手册里面的解释(部分):
       #include <unistd.h>
       int gethostname(char *name, size_t len);
       int sethostname(const char *name, size_t len);
DESCRIPTION
       These  system calls are used to access or to change the hostname of the
       current processor.
RETURN VALUE
       On  success,  zero is returned.  On error, -1 is returned, and errno is
       set appropriately.

2.gethostbyname:
       #include <netdb.h>
       extern int h_errno;
       struct hostent *gethostbyname(const char *name);

可以看到获取的内容保存在一个指针里面。下面我们来看这个指针指向的内容:
       The hostent structure is defined in <netdb.h> as follows:
           struct hostent {
               char  *h_name;            /* official name of host */
               char **h_aliases;         /* alias list */
               int    h_addrtype;        /* host address type */
               int    h_length;          /* length of address */
               char **h_addr_list;       /* list of addresses */
           }
           #define h_addr h_addr_list[0] /* for backward compatibility */
       The members of the hostent structure are:
       h_name The official name of the host.
       h_aliases
              An array of alternative names for the host, terminated by a NULL
              pointer.
       h_addrtype
              The type of address; always AF_INET or AF_INET6 at present.
       h_length
              The length of the address in bytes.
       h_addr_list
              An array of pointers to network addresses for the host (in  net‐
              work byte order), terminated by a NULL pointer.
       h_addr The first address in h_addr_list for backward compatibility.
然后是返回值:
失败返回空。否则返回值指向我们需要的信息的那个结构体。
RETURN VALUE
       The  gethostbyname()  and  gethostbyaddr() functions return the hostent
       structure or a NULL pointer if an error occurs.  On error, the  h_errno
       variable  holds  an  error number.  When non-NULL, the return value may
       point at static data, see the notes below.

实例:

#include<stdio.h>
#include<unistd.h>
#include<netdb.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int main()
{ printf("%s() +++ hello\n", __func__);
char host[] = {};
if(gethostname(host, sizeof(host)) < )
{
perror("gethostname");
return -;
} printf("host:%s\n", host);
struct hostent *myhost = NULL;
if(!(myhost = gethostbyname(host)))
{
perror("gethostbyname");
return -;
}
int i = ;
while(myhost && myhost->h_addr_list[i])
{
printf("ip%d:%s\n", i+, inet_ntoa(*(struct in_addr*)myhost->h_addr_list[i]));
i++;
}
return ;
}

运行:

xcy@xcy-virtual-machine:~/test/gethost$ ./a.out 
main() +++ hello
host:xcy-virtual-machine
ip1:127.0.1.1

二、关于getsockname和getpeername

1.getsockname:获取一个套接字的名字。获取本地的地址和端口信息。
#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
失败返回-1,成功返回0。addr是输入参数,addrlen是输入输出参数

2.getpeername:获取socket的对方的地址
#include <sys/socket.h>
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
失败返回-1,成功返回0。addr是输入参数,addrlen是输入输出参数

注意:
1)对于server来说:
bind以后就可以调用getsockname来获取本地地址和端口了,只不过这样没啥意义,因为就是自己绑定的。
只有在accept以后(就是有连接之后才)才能用getpeername获取client的ip和端口。(client的ip和port也可以在accept函数的第二个参数中带出)
2)对于client来说:
创建socket并不会分配ip和端口。用getsockname获取出来的数据全是0.
在连接(connect)之后才可以用getsockname获取自己的ip和端口。也可以用getpeername获取服务器的。

3.如何使用:伪代码
客户端代码:

......
if(connect(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < )
{
perror("connect");
return -;
}
// 在连接以后才能获取
struct sockaddr_in addr2;
socklen_t len = sizeof(addr2); //
//if(getsockname(sockfd, (struct sockaddr*)&addr2, &len) < 0) // 这个是获取自己的ip和端口
if(getpeername(sockfd, (struct sockaddr*)&addr2, &len) < ) // 这个是获取连接方的
{
perror("getsockname");
return -;
}
printf("Get: port:%d, ip:%s\n", ntohs(addr2.sin_port), inet_ntoa(addr2.sin_addr));
......

服务端代码:

。。。// 前面有bind,listen等动作,这里只处理连接的
while()
{
int conn = accept(listenfd, (struct sockaddr*)&connaddr, &len);
if(conn < )
{
perror("accept");
return -;
}
// 这里的connaddr就跟下面getpeername获取的一样
char strip[] = {};
char *ip = inet_ntoa(connaddr.sin_addr);
strcpy(strip, ip);
printf("new client connect,ip:%s, port:%d\n", strip,ntohs(connaddr.sin_port));
struct sockaddr_in addr2;
socklen_t len = sizeof(addr2);
// if(getsockname(conn, (struct sockaddr*)&addr2, &len) < 0) // 这个是获取自己的ip和端口
if(getpeername(conn, (struct sockaddr*)&addr2, &len) < ) // 这个是获取连接方的。这样其实跟accept参数带出来的数据是一样的
{
perror("getsockname");
return -;
}
printf("get: port:%d, ip:%s\n", ntohs(addr2.sin_port), inet_ntoa(addr2.sin_addr));
deal_connect(conn); // 用来处理连接的函数
}
。。。。。。

关于 getsockname、getpeername和gethostname、gethostbyname的更多相关文章

  1. 获取主机信息,网络信息AIP,getsockname,getpeername,getservbyname,getservbyport,inet_ntop,inet_pton

    获取主机信息 1.ip地址转换,主机字节序 <---> 网络字节序 #include <arpa/inet.h> int inet_pton(int af, const cha ...

  2. 关于getsockname()/getpeername()函数第一次被调用得到0.0.0.0结果的说明

    最近阅读UNIX网络编程第四章时,书本末尾介绍了两个函数getsockname()和getpeername(),可以用于获取服务器端和客户端的IP地址与端口,原本很简单的两个函数,过一眼即明白函数的用 ...

  3. 套接字之 getsockname && getpeername

    getsockname-获取本地地址:比如,在绑定的时候设置端口号为0由系统自动选择端口绑定,或者使用了INADDR_ANY通配所有地址的情况下,后面需要用到具体的地址和端口,就可以用getsockn ...

  4. gethostname gethostbyname gethostbyaddr 获得主机相关信息

    网络编程里经常需要获得主机的相关信息,下面围绕相关的函数以及用到的结构来说明. 获得主机名:int gethostname( char FAR *name, //[out] Pointer to a ...

  5. getsockname()/getpeername()函数第一次被调用得到0.0.0.0结果

    int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); getsockname() returns the cu ...

  6. 一个进程发起多个连接和gethostbyname等函数

    一.在前面讲过的最简单的回射客户/服务器程序中,一个客户端即一个进程,只会发起一个连接,只要稍微修改一下就可以让一个客户端发起多个连 接,然后只利用其中一个连接发送数据. 先来认识一个函数getsoc ...

  7. net programming guid

    Beej's Guide to Network Programming Using Internet Sockets Brian "Beej Jorgensen" Hallbeej ...

  8. socket编程头文件分析

    在socket网络编程中经常用到一些宏定义.结构和函数,这些经常包含在相关的头文件中,使用时直接include相关头文件即可.下面简单描述下相关的一些结构及头文件. 1. sockaddr  / bi ...

  9. UNP总结 Chapter 11 名字与地址转换

    本章讲述在名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IP地址间进行转换,getservbyname和getservbyport在服务器名字和端口 ...

随机推荐

  1. 在微信端使用video标签,播放结束会出现QQ浏览器推荐视频的解决办法(vue)

    会出现播放结束显示QQ浏览器推荐视频的原因:(我是vue的项目,而且我是新手,只是单纯的给大家分享一个方法,代码比较low请自动忽略) 因为在x5(QQ浏览器)内核中,把video标签劫持了,只要是检 ...

  2. 教你五步制作精美的HTML时钟

    学了一段时间的HTML.CSS和JS后,给大家做一款漂亮的不像实力派的HTML时钟,先看图:涉及到的知识点有: CSS3动画.DOM操作.定时器.圆点坐标的计算(好多人是不是已经还给自己的老师了~)  ...

  3. Redis安装及使用笔记

    windows下安装Redis 1.下载Redis的软件包 Redis on github; 2.将软件解压到服务器软件目录; 3.在命令行运行此命令: ./redis-server redis.wi ...

  4. 小随笔:利用Shader给斯坦福兔子长毛和实现雪地效果

    0x00 前言 发现最近没有了写长篇大论的激情,可能是到了冬天了吧.所以这篇小文只是简单介绍下如何在Unity中利用shader很简单的实现雪地效果以及毛皮效果,当然虽然标题写在了一起,但其实这是俩事 ...

  5. Entity Framework——常见报错总结

    1 实体属性配置为IsRequired()对更新的影响 抛出异常类型DbEntityValidationException 表结构: 实体: public class User { public in ...

  6. PHP中MD5函数漏洞

    题目描述 一个网页,不妨设URL为http://haha.com,打开之后是这样的 if (isset($_GET['a']) and isset($_GET['b'])) { if ($_GET[' ...

  7. listview相关代码整理

    虽然listview已经慢慢被替代了,  不过还是整理下 , 留作纪念吧 /** * 获取 listview 实际滚动的距离. [ 相对于listview的第一个项目左上角.] * * @return ...

  8. 逻辑回归,附tensorflow实现

    本文旨在通过二元分类问题.多元分类问题介绍逻辑回归算法,并实现一个简单的数字分类程序 在生活中,我们经常会碰到这样的问题: 根据苹果表皮颜色判断是青苹果还是红苹果 根据体温判断是否发烧 这种答案只有两 ...

  9. 十五、Hadoop学习笔记————Zookeeper客户端的使用

    timeout表示会话超时时间,zookeeper靠与客户的心跳来判断会话是否有效(单位毫秒), -r为只读,表示zookeeper如果与半数以上服务器失去连接则会停止服务,如果有-r参数,则会继续保 ...

  10. ShoneSharp语言(S#)的设计和使用介绍系列(3)— 修炼工具

    ShoneSharp语言(S#)的设计和使用介绍 系列(3)- 修炼工具 作者:Shone 声明:原创文章欢迎转载,但请注明出处,https://www.cnblogs.com/ShoneSharp. ...