目录
一、概念
名称 | 描述 |
套接字 | 用于网络通信,应用与底层网络协议的一个接口。 |
协议 | 交换信息的两个部分之间相互理解的一组规则、约定和数据结构的集合。 |
应用层 | 负责处理应用的特定细节。像FTP、Telnet、E-mail等协议都属于应用层协议。 |
传输层 | 负责为两台机器上的应用程序提供端到端的数据通信,常用协议有TCP(传输控制协议)和UDP(用户数据报协议)。 |
网络层 | 负责IP报文的路由选择,也称为IP层,最重要的功能是路由,每一个IP报文包含源地址和目的地址。常用的IP协议有IPv4和IPv6。IP协议提供无连接的、不可靠的数据报传输服务,只是尽可能传送每一个IP报文到指定的地址,但不保证报文可靠地到达。TCP应用情况下,TCP保证可靠性。UDP应用情况下,可靠性由应用自己保证。 |
网络接口层 | 由设备驱动程序和网卡组成,负责发送和接收IP数据报,应用程序几乎不涉及此层。 |
IPv4 | 使用32位的地址,是20世纪80年代以来一直使用的一种协议。 |
IPv6 | 使用128位的地址,为了应对20世纪90年代中期网络的快速增长而设计的。 |
TCP | 是面向连接的,提供客户端和服务端之间的连接。此协议可以保证为用户提供可靠的、顺序的、不重复的和全双工的字节流。 |
UDP | 是一种面向无连接的协议,其不需要在客户端和服务端建立连接,因此不保证数据报一定到达目的地和到达的顺序。 |
路由 | 指分组从源端到目的端时,决定端到端路径的网络范围的进程。概括总结就是:路由接收数据包->查看目的地址->与路由表进行匹配找到转发端口->转发到该端口。 |
二、TCP/IP参考模型
TCP/IP协议可以抽象成如下层次模型。套接字相当于应用程序和底层协议交互的一个接口,无论我们是从网络读取、写入、配置网络协议都要通过套接字。
三、客户端和服务端使用TCP通信过程
1、同一以太网下
客户端的信息从上至下,通过网络,从下至上到达服务端。
客户端程序将应用数据包装成TCP数据传输给TCP,TCP将自己的数据报包装成IP报文发送给IP,IP再次包装传递给以太网,服务端的IP接收来自网络驱动程序的信息,解开IP层的包装还原回TCP信息传给TCP,TCP解开其TCP包装还原为应用数据传递给服务端程序。
四、函数介绍
1、socket
(1)声明
int socket(int __domain, int __type, int __protocol)
(2)作用
在通信域__domain中创建一个类型为__type、协议为__protocol的套接字。
(3)参数
参数名 | 描述 |
__domain | 通信域,其决定了通信时使用的网络协议族。 |
__type | 套接字类型。 |
__protocol | 协议,从协议族中选一个具体协议。如果不清楚协议族与协议的对应关系,可以使用宏IPPROTO_IP,来让系统选择默认协议。 |
(4)返回值
名称 | 描述 |
成功 | 返回套接字文件描述符。 |
失败 | -1 |
(5)通信域(协议族)相关宏
名称 | 描述 |
AF_INET | 网络通信,IPv4英特网协议。 |
AF_INET6 | 网络通信,IPv6英特网协议。 |
AF_UNIX | UNIX通信域,同一台计算机内两个进程通过文件系统进行通信,以文件系统路径名作为套接字的地址。 |
AF_UNSPEC | 未指定。 |
(6)套接字类型相关宏
名称 | 描述 |
SOCK_STREAM | 字节流套接字,提供面向连接的,双向、可靠、顺序和不重复的数据流,数据没有边界,可支持带外数据。 |
SOCK_DGRAM | 数据报套接字,支持双向通信,但不保证数据报时顺序、可靠和不重复的。 1、进程可能从数据报套接字拿到重复的数据。 2、数据发送顺序和数据接收顺序不同。 3、数据是有边界的,每次往数据报套接字写数据时,数据就会形成一个包。 4、数据报套接字没有连接,每次发包时需指定接收者的地址。 |
SOCK_RAW | 原始套接字,其可以越过高层协议直接访问底层协议(IP协议或网络的物理层) |
(7)协议相关宏
名称 | 描述 |
IPPROTO_IP | IPv4网际协议,如果不清楚协议族与协议的对应关系,可以使用宏IPPROTO_IP,来让系统选择默认协议。 |
IPPROTO_IPV6 | IPv6网际协议 |
IPPROTO_ICMP | 英特网控制报文协议 |
IPPROTO_IGMP | 英特网组管理协议 |
IPPROTO_RAW | 原始IP数据包协议 |
IPPROTO_TCP | 传输控制协议 |
IPPROTO_UDP | 用户数据报协议 |
IPPROTO_SCTP | 流控制传输协议 |
(8)__domain和__type的组合
__domain和__type的组合下的默认协议(会给出名字),support表示支持组合,但无协议名。not support表示不支持。
__type\__domain | AF_INET | AF_INET6 | AF_UNIX |
SOCK_STREAM | TCP | TCP | support |
SOCK_DGRAM | UDP | UDP | support |
SOCK_RAW | IPv4 | IPv6 | not support |
2、socketpair
(1)声明
int socketpair(int domain, int type, int protocol, int socket_vector[2]);
(2)作用
在通信域__domain中创建两个类型为__type、协议为__protocol的套接字,通常应用于父子进程间通信,类型于管道,两个文件描述符一个用于父进程一个用于子进程,不用的一方需关闭,每个套接字都是全双工的,可读可写,但个人感觉没有管道灵活,管道适用于子进程是另外的程序,映射到标准输入输出。匿名管道相关知识点可以参考之前的博客《Unix环境高级编程-学习-04-匿名管道PIPE》。
(3)参数
参数名 | 描述 |
domain | 通信域,其决定了通信时使用的网络协议族。 |
type | 套接字类型。 |
protocol | 协议,从协议族中选一个具体协议。如果不清楚协议族与协议的对应关系,可以使用宏IPPROTO_IP,来让系统选择默认协议。 |
socket_vector | 两个套接字文件描述符,全双工。 |
(4)返回值
名称 | 描述 |
成功 | 0 |
失败 | -1 |
3、shutdown
(1)声明
int shutdown(int socket, int how);
(2)作用
相较于close函数更灵活,可以关闭套接字的部分或全部,例如:套接字是全双工的,我们只是想从套接字读数据,我们就可以关闭它的写功能。
(3)参数
参数名 | 描述 |
socket | 需要关闭的套接字。 |
how | 如何关闭套接字。 |
(4)返回值
名称 | 描述 |
成功 | 0 |
失败 | -1 |
(5)how相关宏
名称 | 描述 |
SHUT_RD | 禁用进一步的接收操作。 |
SHUT_WR | 禁用进一步的发送操作。 |
SHUT_RDWR | 禁用进一步的发送和接收操作。 |
五、参考书籍
编号 | 名称 |
1 | 《UNIX Linux程序设计教程》 |
2 | 《UNIX 环境高级编程》 |
3 | 《UNIX 网络编程》 |
这三本写的都很好,建议大家有时间多阅读。