Linux网络编程: socket(链路层)
socket是什么
在Linux中的网络编程是通过socket接口来进行的。其实socket接口也是一种特殊的I/O(在《深入理解计算机系统》这本书中的IO部分也有提到网络也是一种特殊的IO),它也是一种文件描述符。socket也有一个类似于打开文件的函数调用,该函数返回一个整型的socket描述符,随后的建立连接、数据传输等操作都是通过socket来实现的。
socket的类型
- 流式socket(SOCK_STREAM)流式套接字使用的是TCP协议,由于TCP协议建立在三次握手的基础上,所以这种类型能够提供可靠的、面向连接的通信流,能够保证数据传输的正确性和顺序性
- 数据报socket(SOCK_DGRAM)数据报套接字使用的是UDP协议,由于UDP将数据扔出去之后就不管的桀骜特性,所以该类型定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠、无差错的
- 原始socket原始套接字(如SOCK_RAW)允许对底层协议如IP或ICMP(在网络层,而TCP和UDP都在传输层)进行直接访问,功能比较强大但是使用不便,主要用于一些协议的开发
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
Socket函数中的三个参数其实就是把抽象的socket具体化的条件,domain参数决定了图中所示的第二层通信域,type决定了第三层的通信模式,protocol决定了第四层真正的通信协议。
可供选择的domain
Name | Purpose |
---|---|
AF_UNIX, AF_LOCAL | Local communication |
AF_INET | IPv4 Internet protocols |
AF_INET6 | IPv6 Internet protocols |
AF_IPX | IPX - Novell protocols |
AF_NETLINK | Kernel user interface device |
AF_X25 | ITU-T X.25 / ISO-8208 protocol |
AF_AX25 | Amateur radio AX.25 protocol |
AF_ATMPVC | Access to raw ATM PVCs |
AF_APPLETALK | AppleTalk |
AF_PACKET | Low level packet interface |
AF_ALG | Interface to kernel crypto API |
可供选择的type
Name | Purpose |
---|---|
SOCK_STREAM | 提供排序、可靠、双向、基于连接的字节流。可能支持带外数据传输机制。 |
SOCK_DGRAM | 支持数据报(固定最大长度的无连接、不可靠消息) |
SOCK_SEQPACKET | 为固定最大长度的数据报提供有序、可靠、基于双向连接的数据传输路径;使用者需要在每次输入系统调用时读取整个数据包 |
SOCK_RAW | 提供原始网络协议访问 |
SOCK_RDM | 提供可靠的数据报层,不保证排序 |
SOCK_PACKET | 已过时,不应在新程序中使用 |
... | ... |
protocol
用于制定某个协议的特定类型,即type类型中的某个类型。通常某协议中只有一种特定类型,这样protocol参数仅能设置为0;但是有些协议有多种特定的类型,就需要设置这个参数来选择特定的类型。
- SOCK_STREAM的套接字表示一个双向的字节流,与管道类似。流式的套接字在进行数据收发之前必须已经连接,连接使用 connect() 函数进行。一旦连接,可以使用read()或者write()函数进行数据的传输。流式通信方式保证数据不会丢失或者重复接收,当数据在一段时间内任然没有接受完毕,可以认为这个连接已经死掉。
- SOCK_DGRAM和SOCK_RAW 这个两种套接字可以使用函数 sendto() 来发送数据,使用recvfrom()函数接受数据,recvfrom()接受来自制定IP地址的发送方的数据。
- SOCK_PACKET是一种专用的数据包,它直接从设备驱动接受数据。
- ...
关于socket的更多信息可以在Linux下使用man socket
查看
参考文献:
https://www.cnblogs.com/zhangshenghui/p/6097492.html
https://blog.csdn.net/liuxingen/article/details/44995467