套接字之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