【转自】守夜者 灵感来自于积累 的博客 
【原文链接】http://www.cnblogs.com/nightwatcher/archive/2011/07/03/2096717.html
在最开始接触bind的时候,只是在写基于tcp的server端的时候,知道在listen之前需要先bind一下,用来确保socket能在某个固定的端口监听。而bind的时候,函数参数中的端口填自己将要绑定的端口就行;而IP地址,需要填本机的IP,但是也可以用一个宏INADDR_ANY代替,用这个宏就可以不用查找本机的IP,它就可以代替本机的IP。当时只觉得这个INADDR_ANY比较神奇,但是由于当时觉得用起来很方便,也没出啥问题,也就没有再深究。 
但是最近在做RTSP服务器的时候,有种特殊的应用,导致我不得不对bind这个函数仔细地看一下。 
我们知道无论是UDP还是TCP,socket都会与一个本地的IP和端口想对应,我们往往把这个IP和端口称之为socket的源地址和源端口。当我们作为客户端利用socket去发送数据时,很少会去考虑这个源地址和源端口到底是什么,我们更关心的是它的目的地址和端口。我们往往只有在监听的时候,才去考虑这个源端口,所以我们在监听的时候会去用bind。当我们bind之后,内核就会将这个socket的源端口锁定到我们设定的端口上。但是这就有一个问题,这个bind绑定端口,是将本来没有源端口的socket绑定到我们指定的端口上,还是将一个已经分配了端口的socket重定向到我们指定的端口上呢? 
在《UNIX网络编程》这本书中提到:“如果一个TCP客户或者服务器未曾调用bind捆绑一个端口,当调用connect或listen时,内核就要为相应的套接字选择一个临时接口。”从这句话中可以判断出,其实在调用socket函数创建socket时,内核还并未给socket分配源地址和源端口。而对于UDP,我猜测在调用sendto发送数据时,在未捆绑端口的情况下,内核也会随机分配端口。 
而我遇到的特殊应用要求我在用UDP发送数据之前要告诉对方我的发送端口,这也就意味着我在sendto之前必须要捆绑端口,因此我在发送数据之前就得调用bind函数绑定一下端口了。但是我就在想内核既然有随机分配端口的能力,而我需要的也只是让它绑定一下而不用绑定在固定端口的业务,socket中应该能够提供这种业务。然后果然我发现bind就具备这种能力,当bind的参数中端口地址为0的时候,这时候就是由内核分配端口。这样我就不用考虑端口地址重复的问题,而放心的把这个问题交给内核处理了。 
就在发现bind的这个机制的同时,我发现其实bind对于源地址也同样具备这种处理方式,当系统具有多IP(多网卡)的情况,当我们把bind函数中的ip参数置0时,就是由内核自己选择分配IP。而之前一直觉得很神奇的INADDR_ANY其实一点也不神奇,它的值其实就是0。所以当我们只有单一IP的时候,我们就可以用INADDR_ANY去代替那个单一的IP,因为内核分配的时候只能选择这一个IP。从而造成了INADDR_ANY就是本机IP的现象。

简单分析一下socket中的bind的更多相关文章

  1. 从一个新手容易混淆的例子简单分析C语言中函数调用过程

    某天,王尼玛写了段C程序: #include <stdio.h> void input() { int i; ]; ; i < ; i++) { array[i] = i; } } ...

  2. 简单分析下mybatis中mapper文件中小知识

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-// ...

  3. FFmpeg的HEVC解码器源代码简单分析:概述

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  4. x264源代码简单分析:x264命令行工具(x264.exe)

    ===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...

  5. uboot之run_command简单分析

    本文档简单分析了uboot中命令的实现.run_command函数的实现以及从uboot命令行接收并处理命令的过程. 作者: 彭东林 邮箱: pengdonglin137@163.com http:/ ...

  6. FFmpeg的HEVC解码器源码简单分析:概述

    ===================================================== HEVC源码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg ...

  7. ASIHTTPRequest源码简单分析

      1.前言      ASIHttprequest 是基于CFNetwork的,由于CFNetwork是比较底层的http库,功能比较少,因此,在ASIHttprequest中实现了http协议中比 ...

  8. DELPHI中完成端口(IOCP)的简单分析(1)

    DELPHI中完成端口(IOCP)的简单分析(1)   用DELPHI开发网络代码已经有一段时间了! 我发现在网上用VC来实现完成端口(IOCP)的代码很多,但是使用DELPHI来实现的就比较少了.对 ...

  9. jQuery中的.bind()、.live()和.delegate()之间区别分析

    jQuery中的.bind()..live()和.delegate()之间区别分析,学习jquery的朋友可以参考下.   DOM树   首先,可视化一个HMTL文档的DOM树是很有帮助的.一个简单的 ...

随机推荐

  1. 008.MVC与数据库的交互

    使用ASP.NET MVC实现向数据库插入数据的步骤(程序): (删除,修改,查找)步骤1:创建数据库,创建要使用的表(数据) 表中可以事先插入测试数据步骤2:新建项目,写代码2.1)在配置文件中设置 ...

  2. shell变量引用

    var="www.sina.com.cn" echo ${var#*.} #sina.com.cn 从前向后删 echo ${var##*.} #.cn 贪婪模式从前向后删 ech ...

  3. mysql——数据库存储引擎

    MyISAM INNODB myISAM.innodb.memory MyISAM对事务要求不高,以查询和添加为主,考虑使用. 如bbs中的发帖表,回复表: INNODB存储引擎 对事务要求高,保存的 ...

  4. c#系统泛型委托

    Action<T> 无返回值的系统泛型委托 namespace ConsoleApp1 { public class UserInfo { public int Id { get; set ...

  5. JS中BOM和DOM之间的关系

    一.Javascript组成JavaScript的实现包括以下3个部分:1.核心(ECMAScript):描述了JS的语法和基本对象.2.文档对象模型 (DOM):处理网页内容的方法和接口.3.浏览器 ...

  6. MyBatis中的OGNL教程

    MyBatis中的OGNL教程 有些人可能不知道MyBatis中使用了OGNL,有些人知道用到了OGNL却不知道在MyBatis中如何使用,本文就是讲如何在MyBatis中使用OGNL. 如果我们搜索 ...

  7. SpringDatajpa 使用原生的SQL进行分组查询

    话不多说,直接上代码 dao nativeQuery = true ---> 执行原生的SQL语法,也就是说这段sql拷贝到数据库中,然后就运行. 我们期望的结果: 取值: 取值结果: 结合实际 ...

  8. mysql你问我答

    1.尊敬的先生,请您谈谈mysql数据库的引擎 数据库中的表设定了什么存储引擎,那么该表在数据存储方式.数据更新方式.数据查询性能以及是否支持索引等方面就会有不同的“效果”. mysql引擎大致分两类 ...

  9. 记录一些mysql常用命令

    启动mysql  (ubuntu系统, 以下都是Ubuntu上操作的命令) 这些命令都是可以在任何目录下执行的. # [sudo] 表示可加可不加sudo [sudo] /etc/init.d/mys ...

  10. xml------文件打开样式

    -----添加css样式修饰 引入css样式 浏览器展示 -------- 在服务器上通过 XSLT 转换 XML xsl文件 样式展示