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

getpeername-获取建立连接的对端的地址和端口;

下面为源码分析:

 /*
* Get the local address ('name') of a socket object. Move the obtained
* name to user space.
*/ SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr,
int __user *, usockaddr_len)
{
struct socket *sock;
struct sockaddr_storage address;
int len, err, fput_needed; /* 查找socket */
sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (!sock)
goto out; err = security_socket_getsockname(sock);
if (err)
goto out_put; /* 调用socket操作的getname函数 */
err = sock->ops->getname(sock, (struct sockaddr *)&address, &len, );
if (err)
goto out_put; /* 拷贝地址到用户空间 */
err = move_addr_to_user(&address, len, usockaddr, usockaddr_len); out_put:
fput_light(sock->file, fput_needed);
out:
return err;
}
 /*
* Get the remote address ('name') of a socket object. Move the obtained
* name to user space.
*/ SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr,
int __user *, usockaddr_len)
{
struct socket *sock;
struct sockaddr_storage address;
int len, err, fput_needed; /* 查找socket */
sock = sockfd_lookup_light(fd, &err, &fput_needed);
if (sock != NULL) {
err = security_socket_getpeername(sock);
if (err) {
fput_light(sock->file, fput_needed);
return err;
} /* 调用socket操作的getname获取对端地址,此时最后一个参数为1 */
err =
sock->ops->getname(sock, (struct sockaddr *)&address, &len,
); /* 将地址拷贝到用户空间 */
if (!err)
err = move_addr_to_user(&address, len, usockaddr,
usockaddr_len);
fput_light(sock->file, fput_needed);
}
return err;
}

ipv4情况下,getsockname和getpeername都会调用下面的inet_getname函数;

 /*
* This does both peername and sockname.
*/
int inet_getname(struct socket *sock, struct sockaddr *uaddr,
int *uaddr_len, int peer)
{
struct sock *sk = sock->sk;
struct inet_sock *inet = inet_sk(sk);
DECLARE_SOCKADDR(struct sockaddr_in *, sin, uaddr); /* 设置地址族 */
sin->sin_family = AF_INET; /* 获取对端地址 */
if (peer) {
/* 目的端口为空或者为未连接状态 */
if (!inet->inet_dport ||
((( << sk->sk_state) & (TCPF_CLOSE | TCPF_SYN_SENT)) &&
peer == ))
return -ENOTCONN;
/* 设置目的端口和地址 */
sin->sin_port = inet->inet_dport;
sin->sin_addr.s_addr = inet->inet_daddr;
}
/* 获取本地地址 */
else {
/* 获取接收时ip */
__be32 addr = inet->inet_rcv_saddr; /* 不存在则获取发送时ip */
if (!addr)
addr = inet->inet_saddr; /* 设置端口和地址 */
sin->sin_port = inet->inet_sport;
sin->sin_addr.s_addr = addr;
} /* 填充部分 */
memset(sin->sin_zero, , sizeof(sin->sin_zero)); /* 设置地址长度 */
*uaddr_len = sizeof(*sin);
return ;
}

最新文章

  1. 获取app安装信息私有api
  2. POJ 1330 Nearest Common Ancestors (最近公共祖先LCA + 详解博客)
  3. [BZOJ1951][SDOI2005]古代猪文(数论好题)
  4. iOS - ImageCache 网络图片缓存
  5. JAVA 遍历文件夹下的所有文件
  6. os 计算机的启动
  7. leetcode:Invert Binary Tree
  8. NUMA
  9. WPF多线程问题
  10. CodeForces 415D Mashmokh and ACM
  11. java_监控工具jvisualvm
  12. 偶尔发生File has been moved - cannot be read again,其实是个误解
  13. 消消乐、candy crush类三消游戏程序逻辑分析
  14. KMP算法&amp;next数组总结
  15. Intellij Idea中Backspace无法使用,Ctrl+c/Ctrl+d等等快捷键无法使用的问题的解决
  16. linux基础命令连接命令ln
  17. AS 400 常用命令
  18. QQ邮箱无限扩容 + XMind8 Update8 Crack 小记
  19. IntelliJ IDEA Cannot resolve symbol &#39;&#39;
  20. Mac 键盘符号 及VSCode快捷键 说明

热门文章

  1. 简单了解journalctl
  2. 多线程编程-- part5.1 互斥锁之公平锁-释放锁
  3. linux 网卡配置详情
  4. openstack Rocky系列之keystone:(一)keystone的启动
  5. maven 学习之路一
  6. session共享原理以及PHP 实现多网站共享用户SESSION 数据解决方案
  7. list实现栈以及队列操作
  8. 【51nod1672】区间交
  9. ES修改最大分页数
  10. Vue处理跨域