?? 2_4網(wǎng)絡(luò)代碼閱讀筆記(2) - china linux forum.htm
字號(hào):
<!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網(wǎng)絡(luò)代碼閱讀筆記(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網(wǎng)絡(luò)代碼閱讀筆記(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>技術(shù)論壇|</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>藏經(jīng)閣</FONT></A>| <A href="http://mail.linuxforum.net/"><FONT
color=#ffffff>會(huì)員信箱</FONT></A>| <A href="http://sf.linuxforum.net/"><FONT
color=#ffffff>項(xiàng)目計(jì)劃</FONT></A>| <A
href="http://www.linuxforum.net/poll2/index.php"><FONT
color=#ffffff>在線調(diào)查</FONT></A>| <A href="ftp://ftp.linuxforum.net/"><FONT
color=#ffffff>軟件倉庫</FONT></A>| <A
href="http://www.linuxforum.net/about.php"><FONT
color=#ffffff>關(guān)于本站</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=">討論區(qū)列表</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=&C=4">Linux
高級(jí)應(yīng)用</A> <BR> >> <A
href="http://www.linuxforum.net/forum/postlist.php?Cat=&Board=linuxK&page=120&view=collapsed&sb=5&o=all">Linux內(nèi)核技術(shù)</A>
</SPAN></TD>
<TD align=middle width="33%">此話題閱讀次數(shù): 497 </TD>
<TD align=right width="33%">
<TABLE border=0>
<TBODY>
<TR>
<TD class=navigation noWrap><IMG align=absMiddle alt=*
src="2_4網(wǎng)絡(luò)代碼閱讀筆記(2) - China Linux Forum.files/greyflat.gif">平坦模式
</TD>
<TD class=navigation noWrap><A
href="http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=linuxK&Number=147050&page=120&view=collapsed&sb=5&o=all&vc=1"><IMG
align=absMiddle alt=樹狀模式,一封一封讀 border=0
src="2_4網(wǎng)絡(luò)代碼閱讀筆記(2) - China Linux Forum.files/threaded.gif">樹狀模式</A>
</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> </TD>
<TD align=right class=small><A
href="http://www.linuxforum.net/forum/printthread.php?Cat=&Board=linuxK&main=147050&type=thread"
target=_blank><IMG align=top border=0
src="2_4網(wǎng)絡(luò)代碼閱讀筆記(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=&User=ysqcn&Number=147050&Board=linuxK&what=showflat&page=120&view=collapsed&sb=5&o=all&fpart=1&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網(wǎng)絡(luò)代碼閱讀筆記(2) - China Linux Forum.files/book.gif"
width=15> <B>2.4網(wǎng)絡(luò)代碼閱讀筆記(2)</B> </TD>
<TD align=right width="30%"> </TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD class=lighttable width="83%"><BR>
<P class=post>發(fā)信人: ysqcn (歲月無聲), 信區(qū): llkm <BR>標(biāo) 題: 2.4網(wǎng)絡(luò)代碼閱讀筆記(2)
<BR>發(fā)信站: UNIX編程 (2001年06月12日21:38:25 星期二), 站內(nèi)信件
<BR><BR>接下來就分析sys_bind了,這個(gè)函數(shù)相對簡單點(diǎn),好,讓我們開始吧: <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,&err))!=NULL) <BR>{
<BR>if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0)
<BR>>>>>tcp,udp,raw這里均調(diào)用inet_bind,而packet調(diào)用了packet_bind
<BR>>>>>這里只分析前者,后者在討論af_packet.c的時(shí)候在說 <BR>err =
sock->ops->bind(sock, (struct sockaddr *)address, addrlen);
<BR>>>>>將sock相聯(lián)系的file的應(yīng)用計(jì)數(shù)減一,如果為0,則釋放,此時(shí)就引起一連串的操作
<BR>sockfd_put(sock); <BR>} <BR>return err; <BR>}
<BR><BR>對sockfd_lookup沒有什么好說的了,current.file--->file_struct.fd[套接字描述符]
<BR>---->file.inde----->inode.socket_i,這樣一層層的指下來,就有套接字描述符得到了
<BR>struct socket相應(yīng)的結(jié)構(gòu)了.
<BR>move_addr_to_kernel就是用copy_from_user拷貝用戶給出的地址到字符數(shù)組address中
<BR>去,sock->ops->bind就調(diào)用inet_stream_ops中的函數(shù)了,到了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>>>>>有struct socket得到相應(yīng)的struct
sock <BR>struct sock *sk=sock->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->prot->bind)
<BR>>>>>如果INET層有自己的bind就調(diào)用它,只有raw有,tcp和udp都沒有,為NULL
<BR>>>>>由于udp和tcp的BSD層的bind都是這個(gè)inet_bind,而raw又使用udp的BSD層的
<BR>>>>>例程,故對raw的bind也走到這兒了,不過在這兒raw就與tcp和udp分岔了
<BR>return sk->prot->bind(sk, uaddr, addr_len); <BR>if
(addr_len < sizeof(struct sockaddr_in)) <BR>return -EINVAL;
<BR>>>>>得到bind的地址類型,可以有下面的幾種:RTN_LOCAL,RTN_MULTICAST,
<BR>>>>>RTN_BROADCAST,RTN_UNICAST <BR>chk_addr_ret =
inet_addr_type(addr->sin_addr.s_addr); <BR>......................
<BR>snum = ntohs(addr->sin_port);
<BR>>>>>只有超級(jí)用戶才能綁定1024以下的端口 <BR>if (snum && snum
< PROT_SOCK && !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->state !=
TCP_CLOSE) || <BR>>>>>TCP和UDP在創(chuàng)建套接字的時(shí)候sk->num并沒有賦值,為零
<BR>(sk->num != 0)) <BR>goto out;
<BR>>>>>rcv_saddr用來從hash表中查找,saddr在發(fā)包時(shí)使用
<BR>sk->rcv_saddr = sk->saddr = addr->sin_addr.s_addr;
<BR>if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret ==
RTN_BROADCAST) <BR>>>>>對廣播地址和組播為0 <BR>sk->saddr = 0;
/* Use device */ <BR>/* Make sure we are allowed to bind here. */
<BR>>>>>這里調(diào)用了tcp_v4_get_port,如果snum為0,則查找一個(gè)合適的端口
<BR>>>>>否則檢查端口是不是沒有被使用,將最后得到的合法端口賦值給sk->num
<BR>>>>>下面詳細(xì)分析 <BR>if (sk->prot->get_port(sk,
snum) != 0) { <BR>sk->saddr = sk->rcv_saddr = 0; <BR>err =
-EADDRINUSE; <BR>goto out; <BR>} <BR>if (sk->rcv_saddr)
<BR>sk->userlocks |= SOCK_BINDADDR_LOCK; <BR>if (snum)
<BR>sk->userlocks |= SOCK_BINDPORT_LOCK;
<BR>>>>>這幾個(gè)賦值,意識(shí)很清楚 <BR>sk->sport =
htons(sk->num); <BR>sk->daddr = 0; <BR>sk->dport = 0;
<BR>>>>>sk->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>>>>>定義了一個(gè)桶 <BR>struct tcp_bind_hashbucket *head;
<BR>struct tcp_bind_bucket *tb; <BR>int ret; <BR>local_bh_disable();
<BR>>>>>給定的端口為0,系統(tǒng)分配一個(gè) <BR>if (snum == 0) {
<BR>>>>>本地端口范圍,從1024到4999,可以通過sysctl改變. <BR>int low =
sysctl_local_port_range[0]; <BR>int high =
sysctl_local_port_range[1]; <BR>>>>>有多少端口可以用來分配 <BR>int
remaining = (high - low) + 1; <BR>int rover;
<BR>spin_lock(&tcp_portalloc_lock);
<BR>>>>>tcp_port_rover=1023 <BR>rover = tcp_port_rover;
<BR>do { rover++; <BR>if ((rover < low) || (rover > high))
<BR>rover = low;
<BR>>>>>tcp_bhash是已經(jīng)綁定的端口的hash表,遍歷這個(gè)表,如果發(fā)現(xiàn)有
<BR>>>>>重復(fù)的端口,則遍歷下一個(gè). <BR>head =
&tcp_bhash[tcp_bhashfn(rover)];
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -