WEB开发网
开发学院软件开发Java tcp connection setup的实现(一) 阅读

tcp connection setup的实现(一)

 2009-09-10 00:00:00 来源:WEB开发网   
核心提示: sockfd_lookup_light主要是查找fd对应的socket Java代码 staticstructsocket*sockfd_lookup_light(intfd,int*err,int*fput_needed){structfile*file;structsocket*sock;*

sockfd_lookup_light主要是查找fd对应的socket

Java代码

static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) 
{ 
 struct file *file; 
 struct socket *sock; 
 
 *err = -EBADF; 
///通过fd得到对应的file结构 
 file = fget_light(fd, fput_needed); 
 if (file) { 
///我们在sock_map_fd通过sock_attach_fd中已经把file的private域赋值为socket,因此这里就直接返回socket. 
 sock = sock_from_file(file, err); 
 if (sock) 
  return sock; 
 fput_light(file, *fput_needed); 
 } 
 return NULL; 
}

然后来看inet_bind的实现.

Java代码

int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 
{ 
///取得绑定地址.以及相关的socket和inet_sock. 
 struct sockaddr_in *addr = (struct sockaddr_in *)uaddr; 
 struct sock *sk = sock->sk; 
 struct inet_sock *inet = inet_sk(sk); 
 unsigned short snum; 
 int chk_addr_ret; 
 int err; 
 
 /* If the socket has its own bind function then use it. (RAW) */ 
 if (sk->sk_prot->bind) { 
 err = sk->sk_prot->bind(sk, uaddr, addr_len); 
 goto out; 
 } 
 err = -EINVAL; 
 if (addr_len < sizeof(struct sockaddr_in)) 
 goto out; 
///得到地址类型,比如广播地址之类的. 
 chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); 
 
 err = -EADDRNOTAVAIL; 
 
///主要是判断绑定的地址不是本地时的一些条件判断. 
 if (!sysctl_ip_nonlocal_bind && 
   !inet->freebind && 
   addr->sin_addr.s_addr != htonl(INADDR_ANY) && 
   chk_addr_ret != RTN_LOCAL && 
   chk_addr_ret != RTN_MULTICAST && 
   chk_addr_ret != RTN_BROADCAST) 
 goto out; 
///得到端口号. 
 snum = ntohs(addr->sin_port); 
 err = -EACCES; 
///主要是端口号小于prot_sock(1024)必须得有root权限.如果没有则退出.capable就是用来判断权限的. 
 if (snum && snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE)) 
 goto out; 
 
 /*   We keep a pair of addresses. rcv_saddr is the one 
 *   used by hash lookups, and saddr is used for transmit. 
 * 
 *   In the BSD API these are the same except where it 
 *   would be illegal to use them (multicast/broadcast) in 
 *   which case the sending device address is used. 
 */ 
 lock_sock(sk); 
 
 /* Check these errors (active socket, double bind). */ 
 err = -EINVAL; 
///检测状态是否为close.如果是close状态,说明这个socket前面已经bind过了.而num只有当raw socket时才会不为0 
 if (sk->sk_state != TCP_CLOSE || inet->num) 
 goto out_release_sock; 
 
///设置相应的地址.rcv_saddr是通过hash查找的源地址,而saddr是ip层使用的源地址(ip头的源地址). 
 inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; 
///如果是多播或者广播,设置saddr. 
 if (chk_addr_ret == RTN_MULTICAST || chk_addr_ret == RTN_BROADCAST) 
 inet->saddr = 0; /* Use device */ 
 
///这里get_port用来发现我们绑定的端口,是否被允许使用.而get_port在tcp中,被实例化为inet_csk_get_port,接近着我们会分析它的实现. 
 if (sk->sk_prot->get_port(sk, snum)) { 
 inet->saddr = inet->rcv_saddr = 0; 
 err = -EADDRINUSE; 
 goto out_release_sock; 
 } 
///这两个锁不太理解.不知道谁能解释下. 
 if (inet->rcv_saddr) 
 sk->sk_userlocks |= SOCK_BINDADDR_LOCK; 
 if (snum) 
 sk->sk_userlocks |= SOCK_BINDPORT_LOCK; 
///设置源端口 
 inet->sport = htons(inet->num); 
///目的地址和目的端口,暂时设为0 
 inet->daddr = 0; 
 inet->dport = 0; 
 sk_dst_reset(sk); 
 err = 0; 
out_release_sock: 
 release_sock(sk); 
out: 
 return err; 
}

上一页  1 2 3 4 5 6 7 8 9  下一页

Tags:tcp connection setup

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接