linux 套接字文件是什么

linux中,套接字文件是一种特殊的文件类型,用于通信,它提供了受文件系统访问控制保护的进程间通信。套接字就是支持TCP/IP网络通信的基本操作单元,linux以文件的形式实现套接口,与套接口相应的文件属于sockfs特殊文件系统,创建一个套接口就是在sockfs中创建一个特殊文件,并建立起为实现套接口功能的相关数据结构。

linux 套接字文件是什么

本教程操作环境:linux7.3系统、Dell G3电脑。

套接字文件是什么

套接字文件是一种特殊的文件类型,它用于进程间通信。套接字文件可以被读取、写入和执行。在Linux系统中,套接字文件通常用于网络编程。

使用ls -l 命令查看,第一个字符为 “s”(socket)。

1.png

套接字是一种特殊的文件类型,类似于TCP / IP套接字,它提供了受文件系统访问控制保护的进程间通信。

例如,当您使用netcat在一个终端中打开监听套接字时:

nc -lU socket.sock

然后通过以下方式从另一个终端发送数据:

echo mytext | nc -U socket.sock

mytext出现在第一个终端上。

默认情况下,nc在文件结束字符后停止监听。

套接字Socket

为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口

套接口可以说是网络编程中一个非常重要的概念,linux以文件的形式实现套接口,与套接口相应的文件属于sockfs特殊文件系统,创建一个套接口就是在sockfs中创建一个特殊文件,并建立起为实现套接口功能的相关数据结构。换句话说,对每一个新创建的BSD套接口,linux内核都将在sockfs特殊文件系统中创建一个新的inode。

套接字简介

套接字就是支持TCP/IP网络通信的基本操作单元,是我们进行TCP/IP进行通信的接口。

linux以文件的形式实现套接口,与套接口相应的文件属于sockfs特殊文件系统,创建一个套接口就是在sockfs中创建一个特殊文件,并建立起为实现套接口功能的相关数据结构。换句话说,对每一个新创建的套接字,linux内核都将在sockfs特殊文件系统中创建一个新的inode。

套接字Socket看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。套接字Socket是连接应用程序和网络驱动程序的桥梁,套接字Socket在应用程序中创建,通过绑定与网络驱动建立关系。此后,应用程序送给套接字Socket的数据,由套接字Socket交给网络驱动程序向网络上发送出去。计算机从网络上收到与该套接字Socket绑定IP地址和端口号相关的数据后,由网络驱动程序交给Socket,应用程序便可从该Socket中提取接收到的数据,网络应用程序就是这样通过Socket进行数据的发送与接收的。

操作系统区分不同应用程序进程间的网络通信和连接,主要有3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号。

2.png

Socket原意是 “插座”。通过将这3个参数结合起来,与一个“插座”Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

套接字连接的过程如同(客户)打一个电话到一个大公司,接线员(服务器进程)接听电话并把它转接到你要找的部门,然后再从那里转到你要找的人(服务器套接字),然后接线员(服务器进程)再继续转接其它(客户)的电话。

套接字有本地套接字和网络套接字两种。本地套接字的名字是Linux文件系统中的文件名,一般放在/tmp或/usr/tmp目录中;网络套接字的名字是与客户连接的特定网络有关的服务标识符(端口号或访问点)。这个标识符允许Linux将进入的针对特定端口号的连接转到正确的服务器进程。

套接字类型


常用的TCP/IP协议的3种套接字类型如下所示。

流套接字(SOCK_STREAM):

流套接字用于提供面向连接、可靠的数据传输服务。看到这个我们想到了什么,是不是TCP

该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即TCP(The Transmission Control Protocol)协议。

数据报套接字(SOCK_DGRAM)

数据报套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP(User Datagram Protocol)协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。

原始套接字(SOCK_RAW)

原始套接字(SOCKET_RAW)允许对较低层次的协议直接访问,比如IP、 ICMP协议,它常用于检验新的协议实现,或者访问现有服务中配置的新设备,因为RAW SOCKET可以自如地控制Windows下的多种协议,能够对网络底层的传输机制进行控制,所以可以应用原始套接字来操纵网络层和传输层应用。比如,我们可以通过RAW SOCKET来接收发向本机的ICMP、IGMP协议包,或者接收TCP/IP栈不能够处理的IP包,也可以用来发送一些自定包头或自定协议的IP包。网络监听技术很大程度上依赖于SOCKET_RAW
原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须使用原始套接字。

重要数据结构


下面是在网络编程中比较重要的几个数据结构

表示套接口的数据结构struct socket

用户使用socket系统调用编写应用程序时,通过一个数字来表示一个socket,所有的操作都在该数字上进行,这个数字称为套接字描述符。在系统调用 的实现函数里,这个数字就会被映射成一个表示socket的结构体,该结构体保存了该socket的所有属性和数据。
套接口是由socket数据结构代表的,形式如下

struct socket
{
socket_state state; /*指明套接口的连接状态,一个套接口的连接状态可以有以下几种
套接口是空闲的,还没有进行相应的端口及地址的绑定;还没有连接;正在连接中;已经连接;正在解除连接。*/unsignedlong flags;
structproto_ops ops; /*指明可对套接口进行的各种操作*/structinode inode; /*指向sockfs文件系统中的相应inode*/structfasync_struct *fasync_list; /* Asynchronous wake up list */structfile *file; /*指向sockfs文件系统中的相应文件 */structsock sk; /*任何协议族都有其特定的套接口特性,该域就指向特定协议族的套接口对
象。*/wait_queue_head_t wait;
short type;unsignedchar passcred;
};

描述套接口通用地址的数据结构struct sockaddr

由于历史的缘故,在bind、connect等系统调用中,特定于协议的套接口地址结构指针都要强制转换成该通用的套接口地址结构指针。结构形式如下:

struct sockaddr {
sa_family_t sa_family; /* address family, AF_xxx, sa_family是地址家族,一般都是“AF_xxx”的形式。通常大多用的是都是AF_INET,代表TCP/IP协议族。*/
char sa_data[14];      /*14 bytes of protocol address, sa_data是14字节协议地址。*/
};

此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。但一般编程中并不直接针对此数据结构操作,而是使用另一个与sockaddr等价的数据结构

描述因特网地址结构的数据结构struct sockaddr_in

每个套接字域都有自己的地址格式。

AF_UNIX 域套接字格式:

#include <sys/un.h>
#define UNIX_PATH_MAX
    108struct sockaddr_un { 
    sa_family_t sun_family;               /
    * AF_UNIX */ 
    char        sun_path[UNIX_PATH_MAX];  /* pathname */ 
    };

AF_INET 域套接字格式IPV4:

/* Internet address. */
struct in_addr {
    uint32_t       
    s_addr;     /* address in network byte order */
    };

IP地址是由4个字节组成的一个32位的值。

#include <netinet/in.h>
struct sockaddr_in
{    short sin_family;/*  Addressfamily一般来说AF_INET(地址族)PF_INET(协议族)  */

    unsigned short sin_port;/* Portnumber(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字) */

    struct in_addr sin_addr;/* Internetaddress存储IP地址  */

    unsigned char sin_zero[sizeof(struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof(in_port_t) - sizeof(struct in_addr)];  /* Samesizeasstructsockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/
};

AF_INET6 域套接字格式IPV6:

struct sockaddr_in6 { 
    sa_family_t     sin6_family;   /* AF_INET6 */ 
    in_port_t       sin6_port;     /* port number */ 
    uint32_t        sin6_flowinfo; /* IPv6 flow information */ 
    struct in6_addr sin6_addr;     /* IPv6 address */ 
    uint32_t        sin6_scope_id; /* Scope ID (new in 2.4) */ 
};
struct in6_addr { 
    unsigned char   s6_addr[16];   /* IPv6 address */ 
};

对于应用程序来说,套接字就和文件描述符一样,并且通过一个唯一的整数值来区分。

相关推荐:《Linux视频教程》

以上就是linux 套接字文件是什么的详细内容,更多请关注https://www.sxiaw.com/其它相关文章!