static int sock_bind(int fd, struct sockaddr *umyaddr, int addrlen)
{struct socket *sock;int i;char address[MAX_SOCK_ADDR];int err;if (fd < 0 || fd >= NR_OPEN || current->files->fd[fd] == NULL)return(-EBADF);// 通过文件描述符找到对应的socket,见socket函数源码分析的视图if (!(sock = sockfd_lookup(fd, NULL))) return(-ENOTSOCK);if((err=move_addr_to_kernel(umyaddr,addrlen,address))<0)return err;if ((i = sock->ops->bind(sock, (struct sockaddr *)address, addrlen)) < 0) {return(i);}return(0);
}
```
可见bind函数是直接调用底层af_inet.c的inet_bind
```c
// 给socket绑定一个地址
static int inet_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
{struct sockaddr_in *addr=(struct sockaddr_in *)uaddr;struct sock *sk=(struct sock *)sock->data, *sk2;unsigned short snum = 0 /* Stoopid compiler.. this IS ok */;int chk_addr_ret;/* check this error. */if (sk->state != TCP_CLOSE)return(-EIO);if(addr_len<sizeof(struct sockaddr_in))return -EINVAL;// raw是链路层,不需要端口    if(sock->type != SOCK_RAW){ // 已经绑定了端口if (sk->num != 0) return(-EINVAL);snum = ntohs(addr->sin_port);/** We can't just leave the socket bound wherever it is, it might* be bound to a privileged port. However, since there seems to* be a bug here, we will leave it if the port is not privileged.*/// 端口无效则随机获取一个非root才能使用的端口if (snum == 0) {snum = get_new_socknum(sk->prot, 0);}// 小于1024的端口需要超级用户权限if (snum < PROT_SOCK && !suser()) return(-EACCES);}// 判断ipchk_addr_ret = ip_chk_addr(addr->sin_addr.s_addr);if (addr->sin_addr.s_addr != 0 && chk_addr_ret != IS_MYADDR && chk_addr_ret != IS_MULTICAST)return(-EADDRNOTAVAIL);    /* Source address MUST be ours! */if (chk_addr_ret || addr->sin_addr.s_addr == 0)sk->saddr = addr->sin_addr.s_addr;if(sock->type != SOCK_RAW){/* Make sure we are allowed to bind here. */cli();for(sk2 = sk->prot->sock_array[snum & (SOCK_ARRAY_SIZE -1)];sk2 != NULL; sk2 = sk2->next) {/* should be below! */if (sk2->num != snum) continue;// 端口已经被使用,没有设置可重用标记,比如断开了解后在2msl内是否可以重用if (!sk->reuse){sti();return(-EADDRINUSE);}if (sk2->num != snum) continue;     /* more than one */if (sk2->saddr != sk->saddr) continue;    /* socket per slot ! -FB */// 被监听的端口不能同时被使用if (!sk2->reuse || sk2->state==TCP_LISTEN) {sti();return(-EADDRINUSE);}}sti();// 保证该sk不在sock_array队列里remove_sock(sk);// 挂载到sock_array里put_sock(snum, sk);// tcp头中的源端口sk->dummy_th.source = ntohs(sk->num);sk->daddr = 0;sk->dummy_th.dest = 0;}return(0);
}
复制代码

由代码中可以看到,bind函数主要做的事情是判断一下端口和ip和可用性,然后把sock结构体挂载到协议对应的sock_array哈希列表中。

网络函数bind源码分析相关推荐

  1. jQuery源码分析-10事件处理-Event-事件绑定与删除-bind/unbind+live/die+delegat/unde

    10.4    .bind() .one() 10.4.1  如何使用 .bind( eventType, [eventData], handler(eventObject) )   在匹配的元素上绑 ...

  2. jQuery源码分析-10事件处理-Event-事件绑定与删除-bind/unbind+live/die+delegat/undelegate

    Js代码   作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接. 后文预告:封装事件对象 便 ...

  3. SpringBoot-web开发(二): 页面和图标定制(源码分析)

    [SpringBoot-web系列]前文: SpringBoot-web开发(一): 静态资源的导入(源码分析) 目录 一.首页 1. 源码分析 2. 访问首页测试 二.动态页面 1. 动态资源目录t ...

  4. ceph bluestore源码分析:admin_socket实时获取内存池数据

    环境: 版本:ceph 12.2.1 部署完cephfs 使用ceph-fuse挂载,并写入数据 关键参数: debug_mempool = true 将该参数置为true即可查看详细的blustor ...

  5. koa源码分析-co模块以及thunk

    Thunk以及CO模块 co4.0之前都是返回的thunk函数 之后的都是返回promise thunk thunk:在 JavaScript 语言中,Thunk 函数替换的是将多参数函数,替换成单参 ...

  6. djangorestframework源码分析2:serializer序列化数据的执行流程

    djangorestframework源码分析 本文环境python3.5.2,djangorestframework (3.5.1)系列 djangorestframework源码分析-serial ...

  7. celery源码分析-Task的初始化与发送任务

    celery源码分析 本文环境python3.5.2,celery4.0.2,django1.10.x系列 celery的任务发送 在Django项目中使用了装饰器来包装待执行任务, from cel ...

  8. celery源码分析-wroker初始化分析(上)

    celery源码分析 本文环境python3.5.2,celery4.0.2,django1.10.x系列 celery与Django的配合使用 首先,在安装有django的环境中创建一个django ...

  9. tornado源码分析

    tornado源码分析 本源码为tornado1.0版本 源码附带例子helloworld import tornado.httpserver import tornado.ioloop import ...

最新文章

  1. 阿里云 Redis 开发规范
  2. iOS开源项目周报0420
  3. 系统集成项目管理之项目采购管理
  4. CDN监控系统(一)
  5. 46.一个例子了解C++中异常处理
  6. JZOJ__Day 5:【普及模拟】权势二进制
  7. android上如何写配置文件
  8. python采用pika库使用rabbitmq总结,多篇笔记和示例
  9. sourceTree添加git密钥步骤
  10. 前端学习(2878):原生js模块化+发送弹幕和重置弹幕
  11. IBM Holosofx 进行业务流程管理
  12. html 怎么给li空格,html 空格
  13. tl r402路由器设置_记一次TP-LINK路由器问题排查
  14. 查看修改oracle数据库字符集
  15. SQL SERVER 2000安装教程图文详解
  16. 深入理解Nginx模块开发与架构解析第2版(书签导航正确)
  17. MATLAB中改变默认工作路径的方法
  18. 金融数据类——外汇,CFD
  19. 控件(五)——Gridview控件以SqlDataSource控件为数据源实现换肤功能
  20. 苹果电脑可以装windows系统吗_苹果电脑MacBook双系统安装好后,如何下载Windows支持组件?...

热门文章

  1. 华为上机--质数因子
  2. CSS3学习笔记之loading动画
  3. Myeclipse的web项目导入到Eclipse中
  4. 半岛电视台员工遭iOS iMessage app零点击0day 漏洞利用攻击
  5. idea 常用配置和快捷键
  6. 吴恩达创建deeplearning.ai讲授AI课程 ,向全世界普及深度学习知识
  7. Tomcat创建HTTPS访问,java访问https
  8. iOS 开发 申请定位
  9. 减小Gcc编译程序的体积
  10. 程序定义了多个入口点。使用 /main (指定包含入口点的类型)进行编译