Socket发送数据send, sendto, 和 sendmsg 函数
send, sendto, 和 sendmsg 函数都是用于在网络编程中发送数据的系统调用函数,它们的作用都是将数据从一个套接字(socket)发送到另一个套接字(socket)。
- send: 在连接的套接字上发送数据。
- sendto: 在套接字上向指定的目的地地址发送数据。
- sendmsg: 在套接字上发送消息,可以包含多个数据块并且可以指定控制信息。
在这三个函数中,参数包括套接字描述符、要发送的数据、数据的长度以及控制数据发送的标志。
这些函数之间的主要区别在于它们如何处理目的地地址以及它们是否允许在消息中发送额外的控制信息。
这些函数的用法有所不同,下面分别进行详细的介绍:
send 函数
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
send 函数用于向已连接的套接字发送数据。参数 sockfd 是一个已连接的套接字描述符,buf 是包含要发送数据的缓冲区指针,len 是要发送数据的字节数,flags 是用于控制发送行为的标志,常见的标志包括:
- MSG_OOB:表示发送带外数据(out-of-band data)。
- MSG_DONTROUTE:表示数据不需要路由。
- MSG_NOSIGNAL:表示发送过程中忽略 SIGPIPE 信号,如果在发送数据时对方已经关闭连接,则会产生 SIGPIPE 信号,如果不希望程序因为该信号而终止,则可以使用该标志。
send 函数返回实际发送的字节数,如果发送失败,则返回 -1,并设置 errno 错误码。
sendto 函数
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
sendto 函数用于向指定地址的套接字发送数据。参数 sockfd 是一个套接字描述符,buf 是包含要发送数据的缓冲区指针,len 是要发送数据的字节数,flags 是用于控制发送行为的标志,常见的标志与 send 函数相同。参数 dest_addr 是一个指向目标地址结构体的指针,addrlen 是目标地址结构体的长度。
sendto 函数返回实际发送的字节数,如果发送失败,则返回 -1,并设置 errno 错误码。
sendmsg 函数
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
sendmsg 函数也是向指定套接字发送数据,但它提供了更加灵活的数据发送方式。参数 sockfd 是一个套接字描述符,msg 是一个指向 msghdr 结构体的指针,该结构体定义了要发送的数据和目标地址信息等。flags 是用于控制发送行为的标志,常见的标志与 send 函数相同。
msghdr 结构体定义如下:
struct msghdr {
void *msg_name; /* optional address */
socklen_t msg_namelen; /* size of address */
struct iovec *msg_iov; /* scatter/gather array */
size_t msg_iovlen; /* # elements in msg_iov */
void *msg_control; /* ancillary data, see below */
size_t msg_controllen; /* ancillary data buffer len */
int msg_flags; /* flags on received message */
};
msghdr 结构体中的字段解释如下:
- msg_name:指向一个 sockaddr 结构体,表示要发送数据的目标地址,如果为 NULL,则表示使用已连接的套接字。
- msg_namelen:表示 msg_name 指向的地址结构体的长度,如果为 0,则表示使用已连接的套接字。
- msg_iov:指向一个 iovec 结构体数组,表示要发送的数据分散在多个缓冲区中,可以使用这个数组将这些缓冲区组合成一个数据报发送。
- msg_iovlen:表示 msg_iov 数组的长度,即缓冲区的个数。
- msg_control:指向一个缓冲区,用于存储与数据报相关的控制信息,例如带外数据、IP_TOS 等。
- msg_controllen:表示 msg_control 缓冲区的长度。
- msg_flags:用于表示接收的数据的属性。
sendmsg 函数返回实际发送的字节数,如果发送失败,则返回 -1,并设置 errno 错误码。
总体而言,send、sendto 和 sendmsg 函数都是用于向套接字发送数据的函数,它们的不同之处在于发送数据的方式和用法。在实际编程中,应根据实际情况选择合适的函数进行调用。