套接字之sendto系统调用

Posted wanpengcoder

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了套接字之sendto系统调用相关的知识,希望对你有一定的参考价值。

sendto系统调用用于向指定的目的地址发送数据,其系统调用的流程比较容易理解,如下面所示,其主要完成 (1)将用户数据组织成msghdr,(2)而后调用socket操作的sendmsg;ipv4对应的sendmsg实现为inet_sendmsg,该函数进行端口自动绑定检查和绑定后,调用传输层的sendmsg函数发送数据,比如tcp会调用tcp_sendmsg函数,这里不详细介绍,读到tcp模块在进行补充;

 1 /*
 2  *    Send a datagram to a given address. We move the address into kernel
 3  *    space and check the user space data area is readable before invoking
 4  *    the protocol.
 5  */
 6 
 7 SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
 8         unsigned int, flags, struct sockaddr __user *, addr,
 9         int, addr_len)
10 {
11     struct socket *sock;
12     struct sockaddr_storage address;
13     int err;
14     struct msghdr msg;
15     struct iovec iov;
16     int fput_needed;
17 
18     /* 数据导入到消息 */
19     err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter);
20     if (unlikely(err))
21         return err;
22 
23     /* 获取socket */
24     sock = sockfd_lookup_light(fd, &err, &fput_needed);
25     if (!sock)
26         goto out;
27 
28     msg.msg_name = NULL;
29     msg.msg_control = NULL;
30     msg.msg_controllen = 0;
31     msg.msg_namelen = 0;
32 
33     /* 地址信息 */
34     if (addr) {
35         err = move_addr_to_kernel(addr, addr_len, &address);
36         if (err < 0)
37             goto out_put;
38         msg.msg_name = (struct sockaddr *)&address;
39         msg.msg_namelen = addr_len;
40     }
41 
42     /* 非阻塞标记 */
43     if (sock->file->f_flags & O_NONBLOCK)
44         flags |= MSG_DONTWAIT;
45     msg.msg_flags = flags;
46 
47     /*
48         调用sock->ops->sendmsg,ipv4为inet_sendmsg
49         需要自动绑定端口则绑定,
50         后调用传输层的发送sk->sk_prot->sendmsg 
51     */
52     err = sock_sendmsg(sock, &msg);
53 
54 out_put:
55     fput_light(sock->file, fput_needed);
56 out:
57     return err;
58 }

 

TCP层的sendmsg实现为tcp_sendmsg,详情请移步<TCP层sendmsg系统调用的实现分析>;

以上是关于套接字之sendto系统调用的主要内容,如果未能解决你的问题,请参考以下文章

socket 错误之:OSError: [WinError 10057] 由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。

2-3:套接字(Socket)编程之UDP通信,sockaddr,sockaddr_in,recvfrom,sendto

套接字编程阻塞程序

TCP和UDP的区别

Windows 主机操作系统似乎忽略了通过 linux sendto 使用原始套接字注入的数据包

我收到此错误:stream_socket_sendto() ...未提供地址