Socket笔记速查

0. 本质

socket本质上是一种接口,用于连接网络上进程间相互的通信,每一条连接都有两个相对应的socket
socket起源于"Unix"操作系统,奉行"Everything is a file(一切皆文件)"原则,工作规则为将socket作为一种文件,进行读写(调用网络I/O读写)、打开、关闭等相关操作

1. socket基础函数

1.1 socket()

创建一个socket描述符,作为参数进行读写

int socket(int domain, int type, int protocol);

1.2 bind()

将地址组的特定地址赋给socket

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

1.3 listen()

监听bind绑定的端口号

int listen(int sockfd, int backlog);

1.4 connect()

连接指定计算机的端口

int connnect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

1.5 accept()

接受连接请求,正式建立连接,

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)

注意:这里的第一个参数位服务器的socket描述字,是在服务器生命周期内始终存在的,而第三个参数返回的是一个由内核自动产生的全新socket描述字,仅在连接的时间段内存在

1.6.1 read()/write()

调用网络I/O进行读写

ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const coid *buf, size_t count);

read调试: 读取文件描述符fd,负数为错误,0为正常,EINTR为中断,ECONNREST表示连接中断
write调试: 将buf中nbytes字节写入文件描述符fd,成功返回写入字节数,失败返回-1并设置 errno,EINTR为中断,EPIPE为网络连接中断(对方关闭连接)

1.6.2 send()/recv()

无论服务器还是客户端都使用send/recv来向 TCP 连接另一端 发送/接收 数据

int send(int sockfd, const void *buf, int len, int flags);
int recv(int sockfd, void *buf, size_t len, int flags);

第二个参数为缓冲区,存放 发送/接受 的数据,第三个指明buf(第二个参数)长度,第四个一般为0

需要注意 同步异步阻塞非阻塞 的关系

1.6.3 readv()/writev()

使用readv()/writev()来进行 分散读/集中写

ssize_t readv(int sockfd, const struct iovec *vector, int count);
ssize_t writev(int sockfd, const struct iovec *vector,int count);

第二个参数是iovec的结构体,第三个参数规定了vector(第二个参数)的长度,即多少块内存数据需要读出/写入 sockfd

调试:成功返回 读出/写入 字节数,失败返回-1并设置 errno,此时需要error.h头文件

1.6.4 recvmsg()/sendmsg()

最常用的I/O函数,只要设置好参数,"标题1.6"内所有函数都可对应换成这两个函数调用

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
ssize_t sendmsg(int sockfd, struct msghdr *msg,int flags);

msghdr的结构数据

 struct msghdr
 {
 		//一般用于未连接 套接字描述字(sockfd) 的场合,类似recvfrom/sendto的第五六个参数
		void			*msg_name;		/* protocol address(协议地址),已连接或者不需要可设置NULL */
		socklen_t		msg_namelen;	/* sieze of protocol address(协议地址大小) */
		//这两个成员指定输入或输出缓冲区数组(即iovec结构数组),类似readv/writev的第二三个参数
		struct iovec	*msg_iov;		/* scatter/gather array(发/收 数列,多io缓冲区地址) */
		int				msg_iovlen;		/* #elements in msg_iov(msg_iov中的元素,即缓冲区个数) */
		//这两个成员指定可选的辅助数据的位置和大小,msg_controllen对于recvmsg是一个"值 减去 结果"的参数
		void			*msg_control;	/* ancillary data (cmsghdr struct)(辅助数据地址(消息控制头结构)) */
		socklen_t		msg_controllen;	/* length of ancillary data(辅助数据长度) */
		//recvmsg:仅recvmsg使用(sendmsg会忽略),传递值的 flags 参数(另:所传递 msghdr 结构的 msg_flags 成员,它传递的是引用,因为传递给函数的是该结构的地址)
		int				msg_flags;		/* flags returned by recvmsg() (从recvmsg()函数中获得的返回标志) */
}
1.6.5 recvfrom()/sendto()

一般用于 UDP 协议传输,但经 TCP 中connect函数调用后,也可以用于 TCP 协议传输

int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
in trecvfrom(int sockfd, void *buf, int len, unsigned int lags, struct sockaddr *from, int *fromlen);

to:目的机的IP地址和端口号
tolen:常赋值sizeof(struct sockaddr)
from:struct sockaddr 类型的变量,该变量保存源机的IP地址及端口号
fromlen:常赋值sizeof(struct sockaddr)

sendto调试:返回实际发送长度或-1(错误)
recvfrom调试:返回的fromlen包含实际存入from的数据字节数,如果错误返回-1并设置相应ERRNO

1.7 close()

关闭socket描述字

int close(int fd);

close一个TCP socket的 缺省 行为时将该socket标记为关闭,然后立即返回到调用进程,该描述字将无法被调用进程使用,也就是不能再作为read或write的第一个参数使用

*注意: close操作只是使相应socket描述字引用计数-1,只用当引用计数为0时,才会触发TCP客户端向服务器发送终止连接请求.

2. 主机字节序与网络字节序

主机字节序: 引用标准有 Big-EndianLittle-Endian

网络字节序:在 TCP/IP 首部中,所有二进制整数在网络中传输时要求的次序

在使用时,必须要将主机字节序转换为网络字节序后,再赋给socket

3. 套接字类型

套接字的类型众多,如:
DARPA Internet 地址 (Internet套接字)
本地节点的路径名(Unix套接字)
CCITT X.25地址(X.25套接字)
等…
其中最具代表性的,最经典的也是最常用的为Internet套接字,而根据数据的传输方式,Internet套接字也有许多类型,如:SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET,等等…
在使用socket()创建函数时,必须指定使用哪种套接字

3.1 常用套接字

3.1.1 格流式套接字SOCK_STREAM

格流式套接字(面向连接的套接字),在代码中用SOCK_STREAM表示

SOCK_STREAM 是一种可靠的双向通信数据流,在数据传输过程中,可以保证传输数据准确无误,如损坏或者丢失,可以重新发送

  • 传输中数据不会损失
  • 数据按顺序传输
  • 数据的收发不是同步的(不存在数据边界)

格式流套接字使用 TCP 协议保证传输保证准确性,以 IP 协议作为路由

3.1.2 数据报套接字SOCK_DGRAM

数据报套接字(无连接的套接字),在代码中用SOCK_DGRAM表示

SOCK_DGRAM 让计算机只传输数据,不做数据校验,传输过程中的任何数据的损坏和丢失,都是没法补救的,即使数据错误,也无法重传

  • 强调快速传输,不保证数据的先后顺序
  • 数据可能丢失与损坏
  • 传输数据有大小限制
  • 数据的发送与接受同步

数字报套接字使用 UDP 协议,是一种不可靠的,不按顺序传递的,以追求速度为目的的套接字,以 IP 协议作为路由

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉小兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值