Socket原理及创建
在Linux网络编程模型中,套接字(Socket)用来表示一个网络连接,可以是TCP连接,也可以是UDP连接,在网络通信过程中不管是写数据还是读数据都要通过Socket来完成,因此Socket是网络通信中非常重要的一个工具。下面我们来分析一下Socket的工作原理和创建的过程。
原理说明
在Linux系统中,Socket可以作为一种进程间通信的机制,可以用于不同主机的不同进程之间的通信和数据交换。Linux内核为这一机制提供了一组应用程序接口(API),称为套接字接口(socket API)。应用程序可以通过套接字接口,来使用网络套接字,以进行数据交换。Socket在程序中可以用一个封装好的结构体类型来表示,该结构体主要包含了下面的五个字段:
Socket结构体字段 | 字段的含义 |
---|---|
使用的协议族 | 可以选择TCP、UDP、本地通信等 |
本机IP地址 | 用于表示本机地址 |
本机端口 | 用于表示本机参与通信的进程 |
远程服务器IP地址 | 用于表示远程服务器 |
远程服务器端口 | 用于表示远程服务器参与通信的进程 |
在套接字接口中,以IP地址及通信端口组成套接字地址。远程的套接字地址,以及本地的套接字地址完成连接后,再加上使用的协议,这个五元组,作为套接字对,之后就可以彼此交换数据。
Socket的创建
在实际通信过程中,不管是客户端还是服务器都需要先初始化一个套接字,然后再进行后续操作,Linux内核提供的Socket API中有一个socket函数可以完成这件事,其函数原型如下所示:
1 | int socket(int domain,int type,int protocol);//用于创建Socket实例 |
该函数有三个参数,均为int类型,但是它们有各自的含义,下面我们针对这三个参数进行分析:
domain参数
该参数表示创建Socket所使用的协议域,也称为协议族,协议族决定了socket的地址类型,在通信中必须采用对应的地址。该参数的可能取值如下所示:(1) AF_INET :表示使用IPV4协议
(2)AF_INET6 : 表示使用IPV6协议
(3) AF_UNIX:表示只在本机内通信的套接字
通常我们设置该参数为AF_INET,表示使用IPV4协议进行通信,AF_INET本质上是内核源码中定义的一个宏
#define AF_INET 2
,正好与上面函数原型指定的int类型。type参数
type参数指定套接字的具体类型,该参数决定了Socket的类型,可能取值如下所示:
type参数可能取值 | 取值的具体含义 |
---|---|
SOCK_DGRAM | 创建UDP数据报套接字,使用不连续不可靠的连接 |
SOCK_STREAM | 创建TCP流套接字,使用稳定可靠的连接 |
SOCK_RAW | 创建原始套接字。提供原始网络协议存取 |
SOCK_PACKET | 与网络驱动程序直接通信 |
SOCK_SEQPACKET | 提供连续可靠的数据包连接 |
SOCK_RDM | 提供可靠的数据包连接 |
在实际编程时,我们可以根据自己的需要指定其中一个参数来选择创建的Socket类型。
- protocol参数
protocol参数指定了Socket所使用的协议,常用的字段有:IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。通常情况下设置为0,通过参数domain指定的协议族和参数type指定套接字类型来确定参数。当创建原始套接字,系统无法惟一的协议,这时候就要使用该参数来指定协议。
注意:并不是上面的type和protocol可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择type类型对应的默认协议。
函数的使用
使用该函数需要在程序中包含两个头文件,如下所示
1 |
该函数返回一个int类型的值,如果函数执行成功则返回一个大于0的数,表示一个套接字描述符,可以用来索引一个套接字(类似于文件描述符),在后续的操作中可以使用该描述符来查找套接字并对其进行操作。如果函数执行失败,则返回-1。
参考文章
https://blog.csdn.net/bian_qing_quan11/article/details/71713647