IO操作
我们都知道unix(like)世界里,一切皆文件,而文件是什么呢?文件就是一串二进制流而已,不管socket,还是FIFO、管道、终端,对我们来说,一切都是文件,一切都是流。在信息 交换的过程中,我们都是对这些流进行数据的收发操作,简称为I/O操作(input and output)
而我們如何操作這些流呢,这个时候就需要我们经常见到的文件描述符;最常见的是open一个文件,返回的就是一个文件描述符,而读写操作就是对文件中的数据流进行操作。所以当我们创建一个socket,返回的也同样是一个文件描述符,读写操作就是对网络中数据流进行操作。
流socket(用于tcp连接)
服务端:
- socket() 创建套接字
- bind() 分配套接字地址,绑定到地址
- listen() 等待连接请求, 该socket被标记为被动的,就可以用来接收其他socket的连接;
- accept() 允许连接请求,监听流socket,如果监听时不存在连接,那么将阻塞直到有连接请求到达为止;而且调用返回的结果是一个新的socket,这个新的socket会与执行connect()的对等socket进行连接;
- read()/write() 数据交换,
- close() 关闭连接
客户端:
- socket():创建套接字;
- connect():主动与socket连接;如果连接失败了,根据SUSv3的规定是要关闭这个socket并创建一个新的socket然后再新的socket上进行重写连接;
数据报socket(用于udp连接)
对等的两端:
- socket()创建套接字
- bind()绑定到一个众所周知的地址上;
- recvfron():接受数据报,没有数据报到达时会阻塞;可以获取发送者的地址;
- sento():发送一个数据报到指定地址;
数据报socket是可以使用connect()
来建立“连接”的,但是这个连接并不一定对等,也就是说调用了connect的socket之后可以使用write()来向对等的socket发送数据报,但是对等的socket就并不一定有跟他建立连接了;
SOCK_SEQPACKET
socket的种类其实除了SOCK_STREAM,SOCK_DGRAM,SOCK_RAW之外,还有一种叫做SOCK_SEQPACKET的有序分组套接字
原始套接字(SOCK_RAW):
原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须使用原始套接字。