zoukankan      html  css  js  c++  java
  • 套接字之recvfrom系统调用

    recvfrom系统调用通过用户传入的接收空间构造msghdr,并且调用sock_recvmsg,该函数调用socket操作的recvmsg函数sock->ops->recvmsg,ipv4对应的是inet_recvmsg,该函数调用传输层的sk->sk_prot->recvmsg来接收数据,如tcp则调用tcp_recvmsg,接收完成之后记录地址结构长度信息;

     1 /*
     2  *    Receive a frame from the socket and optionally record the address of the
     3  *    sender. We verify the buffers are writable and if needed move the
     4  *    sender address from kernel to user space.
     5  */
     6 
     7 SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
     8         unsigned int, flags, struct sockaddr __user *, addr,
     9         int __user *, addr_len)
    10 {
    11     struct socket *sock;
    12     struct iovec iov;
    13     struct msghdr msg;
    14     struct sockaddr_storage address;
    15     int err, err2;
    16     int fput_needed;
    17 
    18     /* 构造msghdr */
    19     err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter);
    20     if (unlikely(err))
    21         return err;
    22 
    23     /* 查找消息控制块 */
    24     sock = sockfd_lookup_light(fd, &err, &fput_needed);
    25     if (!sock)
    26         goto out;
    27 
    28     msg.msg_control = NULL;
    29     msg.msg_controllen = 0;
    30     /* Save some cycles and don't copy the address if not needed */
    31     /* 地址结构信息 */
    32     msg.msg_name = addr ? (struct sockaddr *)&address : NULL;
    33     /* We assume all kernel code knows the size of sockaddr_storage */
    34     msg.msg_namelen = 0;
    35     msg.msg_iocb = NULL;
    36     msg.msg_flags = 0;
    37 
    38     /* 非阻塞标记 */
    39     if (sock->file->f_flags & O_NONBLOCK)
    40         flags |= MSG_DONTWAIT;
    41 
    42     /* 接收消息 */
    43     err = sock_recvmsg(sock, &msg, flags);
    44 
    45     /* 拷贝地址到用户空间 */
    46     if (err >= 0 && addr != NULL) {
    47         err2 = move_addr_to_user(&address,
    48                      msg.msg_namelen, addr, addr_len);
    49         if (err2 < 0)
    50             err = err2;
    51     }
    52 
    53     fput_light(sock->file, fput_needed);
    54 out:
    55     return err;
    56 }

    tcp_rcvmsg的实现,请移步<TCP层recvmsg系统调用的实现分析>;

  • 相关阅读:
    unittest详解(二) 跳过用例的执行(skip)
    Selenium获取input值的两种方法:WebElement.getAttribute("value")和WebElement.getText()
    python 函数参数的传递(参数带星号的说明) 元组传递 字典传递
    获取当前运行函数名称和类方法名称
    python中datetime模块中strftime/strptime函数
    面试题
    H5测试-缓存机制
    cp命令
    Java面试
    名词解释。。
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11749319.html
Copyright © 2011-2022 走看看