打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
API函数有send,sendto和sendmsg
在Socket编程中,发送数据报文可供使用的API函数有send,sendto和sendmsg,下面是关于前两个系统调用的原型:
#include <sys/socket.h>
ssize_t send( int socket, const void *buffer, size_t length, int flags );
     请注意它的返回值的类型ssize_t,其含义是signed size。从内核代码中,我们可以看到,在32位系统上,它是int,在64位系统上,它是long。它常用于表示在某一次操作后,缓冲区中可以被读或写的字节数量。相对应的,还有一个数据类型size_t,其含义是unsigned size。常用于表示对象本身的大小,操作sizeof的返回值就是该类型,malloc,memcpy等函数的参数中用该类型表示对象的大小,在32位系统上,它是unsigned int,在64位系统上,它是unsigned long。
     send执行成功,会返回被发送出去的数据报文的字节数,如果执行失败,则会返回-1(所以不能返回size_t类型),并且可以从errno上查找到错误原因。
#include <sys/socket.h>
ssize_t sendto(int socket, const void *message, size_t length,
                 int flags, const struct sockaddr *dest_addr,
                  socklen_t dest_len);
在内核的实现中,send和sendto系统调用最终都会调用到内核函数:
asmlinkage long sys_sendto(int fd, void __user * buff, size_t len, unsigned flags,
       struct sockaddr __user *addr, int addr_len)
     在send系统调用中,参数addr被置为NULL,addr_len为0。sys_sendto首先根据传入的描述符fd,找到对应的struct socket结构体。然后构建内核的消息结构struct msghdr:
struct msghdr {
   void * msg_name;
   int   msg_namelen;
   struct iovec * msg_iov;
   __kernel_size_t msg_iovlen;
   void   * msg_control;
   __kernel_size_t msg_controllen;
   unsigned msg_flags;
};
     msg_name和msg_namelen就是数据报文要发向的对端的地址信息(即sendto系统调用中的addr和addr_len)。当使用send时,它们的值为NULL和0。msg_iov的定义如下:
struct iovec
{
   void __user *iov_base;
   __kernel_size_t iov_len;
};
表示存放待发送数据的一个缓冲区,iov_base是缓冲区的起始地址,指向message, iov_len是缓冲区的长度,指向length。msg_iovlen是缓冲区的数量,对于sendto和send来讲,msg_iovlen都是1。msg_flags即为传入的参数flags,现在暂时不过多的关注flags的应用。msg_control和msg_controllen暂时不关注。
     sys_sendto构建完这些后,调用sock_sendmsg继续执行发送流程,传入参数为struct msghdr和数据的长度。忽略中间的一些不重要的细节,sock_sendmsg继续调用__sock_sendmsg,__sock_sendmsg最后调用struct socket->ops->sendmsg,即对应套接字类型的sendmsg函数,所有的套接字类型的sendmsg函数都是inet_sendmsg,该函数首先检查本地端口是否已绑定,无绑定则执行自动绑定,而后调用具体协议的sendmsg函数。
     下面再来看sendmsg系统调用:
#include <sys/socket.h>
ssize_t sendmsg(int socket, const struct msghdr *message, int flags);
     可以看到,它跟send和sendto的最大区别就是struc msghdr由用户来构建完成,对应的内核处理函数是sys_sendmsg。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Linux下send、sendto、sendmsg函数分析
netlink socket 编程之 why & how - 内核源码 - ChinaUn...
udp客户端和服务代码
进程间传递文件描述符 - UNIX
C语言socket UDP广播的发送和接收示例
UNIX网络编程读书笔记:recvmsg和sendmsg函数
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服