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系统调用的实现分析>;

  • 相关阅读:
    JS DataURL 整理(一)
    JavaScript 与 ECMAScript 的关系
    HTML5 多媒体之<svg>标签 使用
    HTML5 多媒体之<canvas>标签 使用
    [转]信号量---进程间通信 ---php版
    [转]使用PHP的ftok()函数实现基于linux下系统级进程间消息通信demo(消息队列模式)
    【转】php ftok 使用
    [转]Golang调度模型
    【转】如何分析golang程序的内存使用情况---很有用
    【转】Go 中对栈中函数进行内联---这篇讲的不如上一篇,也还可以吧。。
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11749319.html
Copyright © 2011-2022 走看看