【Muduo源码剖析笔记】 网络库之SocketsOps

【Muduo源码剖析笔记】 网络库之SocketsOps

定义了一堆在sockets命名空间的全局函数

sockaddr_cast函数

有四个重载版本,可以接受sockaddr_in6和sockaddr_in这两个专用socket地址结构体,分别用于IPv6和IPv4利用。利用implicit_cast强制转换成了sockaddr类型

createNonblockingOrDie(sa_family_t family):

地址族类型sa_family_t,地址族类型通常与协议族类型对应。用来识别不同协议的,为什么要搞两套东西呢?这是因为之前UNIX有两种风格系统:BSD系统和POSIX系统,对于BSD系统,一直用的是AF,对于POSIX系统,一直用的是PF。Linux作为后起之秀,为了兼容,所以两种都支持,这样两种风格的UNIX下的软件就可以在Linux上运行了。

基于family使用socket系统调用,创建一个该协议类型的文件描述符,

socket(int domain, int type, int protocol)

默认封装的socket提供的服务类型有SOCK_STREAM(流服务),SOCK_NONBLOCK(非阻塞), SOCK_CLOEXEC(用fork调用创建子进程时在子进程中关闭该socket。)选择为TCP协议。

失败的话就会使用 LOG_SYSFATAL。

connect(int sockfd, const struct sockaddr* addr):

通过connect系统调用来主动建立连接,addr是服务器监听的socket地址。一旦建立连接,就唯一标识了这个连接,客户端就通过读写sockfd来与服务器通信。

sockaddr包含了socket的地址族类型、端口号和地址。实际使用的时候转换成通用的地址类型sockaddr就行。不同地址族会有不同的数据结构,比如IPv4使用sockaddr_in。

bindOrDie(int sockfd, const struct sockaddr* addr)

创建socket后,并没有指定使用该地址族中的哪个具体socket地址,将一个socket与socket地址绑定称为给socket命名。就是将socket和实际使用的协议地址进行绑定,创建socket的时候就只是指定了用哪个协议而已。服务器程序通常要命名socket,客户端不需要,采用匿名的方式,使用操作系统自动分配的socket地址。bind将addr地址分配给未命名的sockfd文件描述符。

listenOrDie(int sockfd)

对一个已经命名的sockfd(与一个socket bind)后,系统调用listen来创建一个监听队列来存放后续的客户连接。

int accept(int sockfd, struct sockaddr_in6* addr)

从listen监听队列中接收一个连接,函数内部实际调用accept4

accept4(sockfd, sockaddr_cast(addr),&addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC)

accept4()函数共有4个参数,相比accept()多了一个flags的参数,用户可以通过此参数直接设置套接字的一些属性.

sockfd是已经在监听socket了,addr参数用来获取被接收连接的socket地址。

如果接收连接失败就会保存日志信息。

成功就会返回一个与新连接的socket,该socket唯一标识了这个连接,服务器通过对这个socket读写来实现对应客户端的通信。

ssize_t read(int sockfd, void *buf, size_t count);

从sockfd中读取count长度的数据存放在buf中。

ssize_t readv(int sockfd, const struct iovec *iov, int iovcnt);

iovec结构体类型的指针

struct iovec
{

​	void *iov_base; //内存起始地址

​	size_t iov_len;   //内存长度

}
write(int sockfd, const void *buf, size_t count);
close(int sockfd)
shutdownWrite(int sockfd)
toIp(char* buf, size_t size,const struct sockaddr* addr);

如果addr(包含端口号、地址族以及相应的地址等信息)表示是IPv4的话。使用sockaddr_in 数据保存addr,通过

 const struct sockaddr_in* addr4 = sockaddr_in_cast(addr);
 //把sockaddr cast成IPv4专用的socket地址结构体
::inet_ntop(AF_INET, &addr4->sin_addr, buf, static_cast<socklen_t>(size));

//将数值格式转化为点分十进制的ip地址格式

AF_INET表示地址族,sin_addr是具体地址,buf是char*类型的。

toIpPort(char* buf, size_t size,const struct sockaddr* addr);

好像是把addr地址的IP和端口号全部放进buf中。

int getSocketError(int sockfd)
sockaddr_in6 sockets::getLocalAddr(int sockfd) :
::getsockname(sockfd, sockaddr_cast(&localaddr), &addrlen)

getsockname可以获得一个与socket相关的地址。 服务器端可以通过它得到相关客户端地址。

sockaddr_in6 sockets::getPeerAddr(int sockfd)
::getpeername(sockfd, sockaddr_cast(&peeraddr), &addrlen)

getpeername函数用于获取与某个套接字关联的外地协议地址

sockets::isSelfConnect(int sockfd)

通过获取本端地址和外端地址,判断是否是自己连接自己的sockfd。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值