⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2_4网络代码阅读笔记(2) - china linux forum.htm

📁 包括较少的一些linux下的网络代码阅读笔记
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0111)http://www.linuxforum.net/forum/showflat.php?Cat=&Board=linuxK&Number=147050&page=120&view=collapsed&sb=5&o=all -->
<HTML><HEAD><TITLE>2.4网络代码阅读笔记(2) - China Linux Forum</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD>
<BODY>
<CENTER><FONT color=red>著名软件中国镜像:</FONT> <A 
href="http://apache.linuxforum.net/"><FONT color=red>Apache|</FONT></A> <A 
href="http://php.linuxforum.net/"><FONT color=red>Php|</FONT></A> <A 
href="http://debian.linuxforum.net/"><FONT color=red>Debian|</FONT></A> <A 
href="http://mysql.linuxforum.net/"><FONT color=red>Mysql|</FONT></A> <A 
href="http://proftpd.linuxforum.net/"><FONT color=red>Proftp|</FONT></A> <A 
href="http://qmail.linuxforum.net/top.html"><FONT color=red>Qmail|</FONT></A> <A 
href="http://samba.linuxforum.net/samba.html"><FONT color=red>Samba|</FONT></A> 
<A href="http://www1.cn.squid-cache.org/"><FONT color=red>Squid|</FONT></A> <A 
href="http://xfree86.linuxforum.net/"><FONT color=red>Xfree86|</FONT></A> <A 
href="http://cpan.linuxforum.net/"><FONT color=red>CPAN|</FONT></A> <A 
href="http://ldp.linuxforum.net/"><FONT color=red>LDP|</FONT></A> <A 
href="http://gnu.linuxforum.net/"><FONT 
color=red>GNU|</FONT></A></CENTER><BR><LINK 
href="2_4网络代码阅读笔记(2) - China Linux Forum.files/stylesheet2.css" rel=stylesheet 
type=text/css><SPAN class=onbody>
<TABLE align=center border=0 cellPadding=3 cellSpacing=0 class=p9 width="95%">
  <TBODY>
  <TR align=right bgColor=#0099cc vAlign=center>
    <TD align=left width="20%"><A 
      href="http://www.linuxforum.net/index.php"><FONT 
      color=#ffffff>中国Linux论坛首页</FONT></A></TD>
    <TD width="80%"><A 
      href="http://www.linuxforum.net/forum/ubbthreads.php"><FONT 
      color=#ffffff>技术论坛|</FONT></A><FON color="#FFFFFF" t> <A 
      href="http://www.linuxforum.net/docnew/index.php"><FONT 
      color=#ffffff>文章荟萃</FONT></A><FONT color=#ffffff>| <A 
      href="http://www.linuxforum.net/books/index.php"><FONT 
      color=#ffffff>藏经阁</FONT></A>| <A href="http://mail.linuxforum.net/"><FONT 
      color=#ffffff>会员信箱</FONT></A>| <A href="http://sf.linuxforum.net/"><FONT 
      color=#ffffff>项目计划</FONT></A>| <A 
      href="http://www.linuxforum.net/poll2/index.php"><FONT 
      color=#ffffff>在线调查</FONT></A>| <A href="ftp://ftp.linuxforum.net/"><FONT 
      color=#ffffff>软件仓库</FONT></A>| <A 
      href="http://www.linuxforum.net/about.php"><FONT 
      color=#ffffff>关于本站</FONT></A>| </FONT></TD></TR></TBODY></TABLE><BR></SPAN>
<TABLE align=center border=0 cellPadding=0 cellSpacing=0 width="95%">
  <TBODY>
  <TR>
    <TD class=tableborders>
      <TABLE border=0 cellPadding=3 cellSpacing=1 width="100%">
        <TBODY>
        <TR>
          <TD align=right class=menubar><A 
            href="http://www.linuxforum.net/forum/ubbthreads.php?Cat=">讨论区列表</A> 
            | <A href="http://www.linuxforum.net/forum/search.php?Cat=">搜寻文章</A> 
            | <A 
            href="http://www.linuxforum.net/forum/newuser.php?Cat=">新用户注册</A> | 
            <A href="http://www.linuxforum.net/forum/login.php?Cat=">登入论坛</A> | 
            <A href="http://www.linuxforum.net/forum/online.php?Cat=">在线用户</A> | 
            <A 
            href="http://www.linuxforum.net/forum/faq_chinese.php?Cat=">常见问题</A> 
          </TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
<P>
<TABLE align=center border=0 cellPadding=0 cellSpacing=0 width="95%">
  <TBODY>
  <TR>
    <TD class=tableborders>
      <TABLE border=0 cellPadding=3 cellSpacing=1 width="100%">
        <TBODY>
        <TR class=darktable>
          <TD>
            <TABLE cellPadding=0 cellSpacing=0 width="100%">
              <TBODY>
              <TR class=darktable>
                <TD align=left width="33%"><SPAN class=catandforum><A 
                  href="http://www.linuxforum.net/forum/ubbthreads.php?Cat=&amp;C=4">Linux 
                  高级应用</A> <BR>&nbsp;&nbsp;&nbsp;&gt;&gt; <A 
                  href="http://www.linuxforum.net/forum/postlist.php?Cat=&amp;Board=linuxK&amp;page=120&amp;view=collapsed&amp;sb=5&amp;o=all">Linux内核技术</A> 
                  </SPAN></TD>
                <TD align=middle width="33%">此话题阅读次数: 497 </TD>
                <TD align=right width="33%">
                  <TABLE border=0>
                    <TBODY>
                    <TR>
                      <TD class=navigation noWrap><IMG align=absMiddle alt=* 
                        src="2_4网络代码阅读笔记(2) - China Linux Forum.files/greyflat.gif">平坦模式&nbsp; 
                      </TD>
                      <TD class=navigation noWrap><A 
                        href="http://www.linuxforum.net/forum/showthreaded.php?Cat=&amp;Board=linuxK&amp;Number=147050&amp;page=120&amp;view=collapsed&amp;sb=5&amp;o=all&amp;vc=1"><IMG 
                        align=absMiddle alt=树状模式,一封一封读 border=0 
                        src="2_4网络代码阅读笔记(2) - China Linux Forum.files/threaded.gif">树状模式</A>&nbsp; 
                      </TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<TABLE align=center border=0 cellPadding=4 cellSpacing=0 width="95%">
  <TBODY>
  <TR>
    <TD align=left class=small>&nbsp; </TD>
    <TD align=right class=small><A 
      href="http://www.linuxforum.net/forum/printthread.php?Cat=&amp;Board=linuxK&amp;main=147050&amp;type=thread" 
      target=_blank><IMG align=top border=0 
      src="2_4网络代码阅读笔记(2) - China Linux Forum.files/printthread.gif"> 打印</A> 
  </TD></TR></TBODY></TABLE>
<TABLE align=center border=0 cellPadding=0 cellSpacing=0 width="95%">
  <TBODY>
  <TR>
    <TD class=tableborders>
      <TABLE border=0 cellPadding=3 cellSpacing=1 width="100%">
        <TBODY>
        <TR>
          <TD class=darktable rowSpan=2 vAlign=top width="17%"><A 
            name=Post147050></A><A 
            href="http://www.linuxforum.net/forum/showprofile.php?Cat=&amp;User=ysqcn&amp;Number=147050&amp;Board=linuxK&amp;what=showflat&amp;page=120&amp;view=collapsed&amp;sb=5&amp;o=all&amp;fpart=1&amp;vc=1">ysqcn</A><BR><SPAN 
            class=small>(newbie)<BR>08/01/01 20:25<BR></SPAN></TD>
          <TD class=subjecttable width="83%">
            <TABLE border=0 class=subjecttable width="100%">
              <TBODY>
              <TR>
                <TD align=left width="70%"><IMG height=15 
                  src="2_4网络代码阅读笔记(2) - China Linux Forum.files/book.gif" 
                  width=15> <B>2.4网络代码阅读笔记(2)</B> </TD>
                <TD align=right width="30%">&nbsp; </TD></TR></TBODY></TABLE></TD></TR>
        <TR>
          <TD class=lighttable width="83%"><BR>
            <P class=post>发信人: ysqcn (岁月无声), 信区: llkm <BR>标 题: 2.4网络代码阅读笔记(2) 
            <BR>发信站: UNIX编程 (2001年06月12日21:38:25 星期二), 站内信件 
            <BR><BR>接下来就分析sys_bind了,这个函数相对简单点,好,让我们开始吧: <BR><BR>asmlinkage long 
            sys_bind(int fd, struct sockaddr *umyaddr, int addrlen) <BR>{ 
            <BR>struct socket *sock; <BR>char address[MAX_SOCK_ADDR]; <BR>int 
            err; <BR>if((sock = sockfd_lookup(fd,&amp;err))!=NULL) <BR>{ 
            <BR>if((err=move_addr_to_kernel(umyaddr,addrlen,address))&gt;=0) 
            <BR>&gt;&gt;&gt;&gt;tcp,udp,raw这里均调用inet_bind,而packet调用了packet_bind 
            <BR>&gt;&gt;&gt;&gt;这里只分析前者,后者在讨论af_packet.c的时候在说 <BR>err = 
            sock-&gt;ops-&gt;bind(sock, (struct sockaddr *)address, addrlen); 
            <BR>&gt;&gt;&gt;&gt;将sock相联系的file的应用计数减一,如果为0,则释放,此时就引起一连串的操作 
            <BR>sockfd_put(sock); <BR>} <BR>return err; <BR>} 
            <BR><BR>对sockfd_lookup没有什么好说的了,current.file---&gt;file_struct.fd[套接字描述符] 
            <BR>----&gt;file.inde-----&gt;inode.socket_i,这样一层层的指下来,就有套接字描述符得到了 
            <BR>struct socket相应的结构了. 
            <BR>move_addr_to_kernel就是用copy_from_user拷贝用户给出的地址到字符数组address中 
            <BR>去,sock-&gt;ops-&gt;bind就调用inet_stream_ops中的函数了,到了BSD层了,为inet_bind: 
            <BR><BR>static int inet_bind(struct socket *sock, struct sockaddr 
            *uaddr, int addr_len) <BR>{ <BR>struct sockaddr_in *addr=(struct 
            sockaddr_in *)uaddr; <BR>&gt;&gt;&gt;&gt;有struct socket得到相应的struct 
            sock <BR>struct sock *sk=sock-&gt;sk; <BR>unsigned short snum; 
            <BR>int chk_addr_ret; <BR>int err; <BR>/* If the socket has its own 
            bind function then use it. (RAW) */ <BR>if(sk-&gt;prot-&gt;bind) 
            <BR>&gt;&gt;&gt;&gt;如果INET层有自己的bind就调用它,只有raw有,tcp和udp都没有,为NULL 
            <BR>&gt;&gt;&gt;&gt;由于udp和tcp的BSD层的bind都是这个inet_bind,而raw又使用udp的BSD层的 
            <BR>&gt;&gt;&gt;&gt;例程,故对raw的bind也走到这儿了,不过在这儿raw就与tcp和udp分岔了 
            <BR>return sk-&gt;prot-&gt;bind(sk, uaddr, addr_len); <BR>if 
            (addr_len &lt; sizeof(struct sockaddr_in)) <BR>return -EINVAL; 
            <BR>&gt;&gt;&gt;&gt;得到bind的地址类型,可以有下面的几种:RTN_LOCAL,RTN_MULTICAST, 
            <BR>&gt;&gt;&gt;&gt;RTN_BROADCAST,RTN_UNICAST <BR>chk_addr_ret = 
            inet_addr_type(addr-&gt;sin_addr.s_addr); <BR>...................... 
            <BR>snum = ntohs(addr-&gt;sin_port); 
            <BR>&gt;&gt;&gt;&gt;只有超级用户才能绑定1024以下的端口 <BR>if (snum &amp;&amp; snum 
            &lt; PROT_SOCK &amp;&amp; !capable(CAP_NET_BIND_SERVICE)) <BR>return 
            -EACCES; <BR>lock_sock(sk); <BR>/* Check these errors (active 
            socket, double bind). */ <BR>err = -EINVAL; <BR>if ((sk-&gt;state != 
            TCP_CLOSE) || <BR>&gt;&gt;&gt;&gt;TCP和UDP在创建套接字的时候sk-&gt;num并没有赋值,为零 
            <BR>(sk-&gt;num != 0)) <BR>goto out; 
            <BR>&gt;&gt;&gt;&gt;rcv_saddr用来从hash表中查找,saddr在发包时使用 
            <BR>sk-&gt;rcv_saddr = sk-&gt;saddr = addr-&gt;sin_addr.s_addr; 
            <BR>if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == 
            RTN_BROADCAST) <BR>&gt;&gt;&gt;&gt;对广播地址和组播为0 <BR>sk-&gt;saddr = 0; 
            /* Use device */ <BR>/* Make sure we are allowed to bind here. */ 
            <BR>&gt;&gt;&gt;&gt;这里调用了tcp_v4_get_port,如果snum为0,则查找一个合适的端口 
            <BR>&gt;&gt;&gt;&gt;否则检查端口是不是没有被使用,将最后得到的合法端口赋值给sk-&gt;num 
            <BR>&gt;&gt;&gt;&gt;下面详细分析 <BR>if (sk-&gt;prot-&gt;get_port(sk, 
            snum) != 0) { <BR>sk-&gt;saddr = sk-&gt;rcv_saddr = 0; <BR>err = 
            -EADDRINUSE; <BR>goto out; <BR>} <BR>if (sk-&gt;rcv_saddr) 
            <BR>sk-&gt;userlocks |= SOCK_BINDADDR_LOCK; <BR>if (snum) 
            <BR>sk-&gt;userlocks |= SOCK_BINDPORT_LOCK; 
            <BR>&gt;&gt;&gt;&gt;这几个赋值,意识很清楚 <BR>sk-&gt;sport = 
            htons(sk-&gt;num); <BR>sk-&gt;daddr = 0; <BR>sk-&gt;dport = 0; 
            <BR>&gt;&gt;&gt;&gt;sk-&gt;dst_cache = NULL; <BR>sk_dst_reset(sk); 
            <BR>err = 0; <BR>out: <BR>release_sock(sk); <BR>return err; <BR>} 
            <BR><BR><BR>下面是tcp_v4_get_port了,看看linux是怎样管理端口的: <BR>/* Obtain a 
            reference to a local port for the given sock, <BR>* if snum is zero 
            it means select any available local port. <BR>*/ <BR>static int 
            tcp_v4_get_port(struct sock *sk, unsigned short snum) <BR>{ 
            <BR>&gt;&gt;&gt;&gt;定义了一个桶 <BR>struct tcp_bind_hashbucket *head; 
            <BR>struct tcp_bind_bucket *tb; <BR>int ret; <BR>local_bh_disable(); 
            <BR>&gt;&gt;&gt;&gt;给定的端口为0,系统分配一个 <BR>if (snum == 0) { 
            <BR>&gt;&gt;&gt;&gt;本地端口范围,从1024到4999,可以通过sysctl改变. <BR>int low = 
            sysctl_local_port_range[0]; <BR>int high = 
            sysctl_local_port_range[1]; <BR>&gt;&gt;&gt;&gt;有多少端口可以用来分配 <BR>int 
            remaining = (high - low) + 1; <BR>int rover; 
            <BR>spin_lock(&amp;tcp_portalloc_lock); 
            <BR>&gt;&gt;&gt;&gt;tcp_port_rover=1023 <BR>rover = tcp_port_rover; 
            <BR>do { rover++; <BR>if ((rover &lt; low) || (rover &gt; high)) 
            <BR>rover = low; 
            <BR>&gt;&gt;&gt;&gt;tcp_bhash是已经绑定的端口的hash表,遍历这个表,如果发现有 
            <BR>&gt;&gt;&gt;&gt;重复的端口,则遍历下一个. <BR>head = 
            &amp;tcp_bhash[tcp_bhashfn(rover)]; 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -