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

posted @   AlexAlex  阅读(1234)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示