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

tcp connection setup的实现(三)

 2009-09-10 00:00:00 来源:WEB开发网   
核心提示:先来看下accept的实现. 其实accept的作用很简单,就是从accept队列中取出三次握手完成的socket,并将它关联到vfs上(其实操作和调用 sys_socket时新建一个socket类似).然后返回.这里还有个要注意的,如果这个传递给accept的socket是非阻塞的话,就算 accept队列为空,也会

先来看下accept的实现.

其实accept的作用很简单,就是从accept队列中取出三次握手完成的socket,并将它关联到vfs上(其实操作和调用 sys_socket时新建一个socket类似).然后返回.这里还有个要注意的,如果这个传递给accept的socket是非阻塞的话,就算 accept队列为空,也会直接返回,而是阻塞的话就会休眠掉,等待accept队列有数据后唤醒他.

接下来我们就来看它的实现,accept对应的系统调用是 sys_accept,而他则会调用do_accept,因此我们直接来看do_accept:

Java代码 long do_accept(int fd, struct sockaddr __user *upeer_sockaddr, 
    int __user *upeer_addrlen, int flags) 
{ 
 struct socket *sock, *newsock; 
 struct file *newfile; 
 int err, len, newfd, fput_needed; 
 struct sockaddr_storage address; 
............................................. 
///这个函数前面已经分析过了,也就是通过fd,得到相应的socket. 
 sock = sockfd_lookup_light(fd, &err, &fput_needed); 
 if (!sock) 
 goto out; 
 
 err = -ENFILE; 
///新建一个socket,也就是这个函数将要返回的socket.这里注意我们得到的是一个socket,而不是sock.下面会解释为什么这么做. 
 if (!(newsock = sock_alloc())) 
 goto out_put; 
 
 newsock->type = sock->type; 
 newsock->ops = sock->ops; 
 
 /* 
 * We don't need try_module_get here, as the listening socket (sock) 
 * has the protocol module (sock->ops->owner) held. 
 */ 
 __module_get(newsock->ops->owner); 
///找到一个新的可用的文件句柄,以及file结构.是为了与刚才新建的socket关联起来. 
 newfd = sock_alloc_fd(&newfile, flags & O_CLOEXEC); 
 if (unlikely(newfd < 0)) { 
 err = newfd; 
 sock_release(newsock); 
 goto out_put; 
 } 
///将新的socket和file关联起来.(这里所做的和我们第一篇所分析的信件socket的步骤是一样的,不理解的,可以去看我前面的blog 
 err = sock_attach_fd(newsock, newfile, flags & O_NONBLOCK); 
 if (err < 0) 
 goto out_fd_simple; 
 
 err = security_socket_accept(sock, newsock); 
 if (err) 
 goto out_fd; 
///调用inet_accept 
 err = sock->ops->accept(sock, newsock, sock->file->f_flags); 
 if (err < 0) 
 goto out_fd; 
///这里也就是取得accept到的句柄的源地址.也就是填充传递进来的upeer_sockaddr. 
 if (upeer_sockaddr) { 
 if (newsock->ops->getname(newsock, (struct sockaddr *)&address, 
    &len, 2) < 0) { 
  err = -ECONNABORTED; 
  goto out_fd; 
 } 
 err = move_addr_to_user((struct sockaddr *)&address, 
   len, upeer_sockaddr, upeer_addrlen); 
 if (err < 0) 
  goto out_fd; 
 } 
 
 /* File flags are not inherited via accept() unlike another OSes. */ 
///最终将新的file结构和fd关联起来,其实也就是最终将这个fd关联到当前进程的files中. 
 fd_install(newfd, newfile); 
 err = newfd; 
 
 security_socket_post_accept(sock, newsock); 
 
out_put: 
///文件描述符的引用计数加一. 
 fput_light(sock->file, fput_needed); 
out: 
///返回句柄. 
 return err; 
....................................... 
}

1 2 3 4 5 6  下一页

Tags:tcp connection setup

编辑录入:爽爽 [复制链接] [打 印]
[]
  • 好
  • 好的评价 如果觉得好,就请您
      0%(0)
  • 差
  • 差的评价 如果觉得差,就请您
      0%(0)
赞助商链接