리눅스에서 소켓 파일은 통신에 사용되는 특수 파일 형식으로, 파일 시스템 액세스 제어로 보호되는 프로세스 간 통신을 제공합니다. 소켓은 TCP/IP 네트워크 통신을 지원하는 기본 연산 단위로, 리눅스에서는 소켓을 파일 형태로 구현하는데, 소켓에 해당하는 파일은 sockfs 특수 파일 시스템에 속한다. sockfs에서 소켓 기능을 구현하기 위해 관련 데이터 구조를 설정합니다.
이 튜토리얼의 운영 환경: linux7.3 시스템, Dell G3 컴퓨터.
소켓 파일은 프로세스 간 통신에 사용되는 특수 파일 형식입니다. 소켓 파일을 읽고, 쓰고, 실행할 수 있습니다. Linux 시스템에서는 소켓 파일이 일반적으로 네트워크 프로그래밍에 사용됩니다.
보려면 ls -l
명령을 사용하세요. 첫 번째 문자는 "s"(소켓)입니다.
소켓은 파일 시스템 액세스 제어로 보호되는 프로세스 간 통신을 제공하는 TCP/IP 소켓과 유사한 특수 파일 유형입니다.
예를 들어, netcat을 사용하여 한 터미널에서 청취 소켓을 열 때:
nc -lU socket.sock
그런 다음 다음을 통해 다른 터미널에서 데이터를 보냅니다.
echo mytext | nc -U socket.sock
mytext가 첫 번째 터미널에 나타납니다.
기본적으로 nc는 파일 끝 문자 이후 청취를 중지합니다.
다양한 애플리케이션 프로세스와 연결을 구별하기 위해 많은 컴퓨터 운영 체제는 애플리케이션이 TCP/IP 프로토콜과 상호 작용할 수 있도록 Socket(소켓)이라는 인터페이스를 제공합니다.
소켓은 네트워크 프로그래밍에서 매우 중요한 개념이라고 할 수 있습니다. 리눅스는 소켓을 파일 형태로 구현합니다. 소켓에 해당하는 파일은 sockfs 특수 파일 시스템에 속합니다. 그리고 소켓 기능을 실현하기 위해 관련 데이터 구조를 설정합니다. 즉, 새로 생성된 각 BSD 소켓에 대해 Linux 커널은 sockfs 특수 파일 시스템에 새 inode를 생성합니다.
소켓 소개
소켓은 TCP/IP 네트워크 통신을 지원하는 기본 운영 단위이자 TCP/IP 통신을 위한 인터페이스입니다.
Linux는 소켓을 파일 형태로 구현합니다. 소켓에 해당하는 파일은 sockfs 특수 파일 시스템에 속합니다. 소켓을 생성한다는 것은 sockfs에 특수 파일을 생성하고 소켓 기능을 구현하기 위한 관련 데이터 구조를 설정한다는 의미입니다. 즉, 새로 생성된 각 소켓에 대해 Linux 커널은 sockfs 특수 파일 시스템에 새 inode를 생성합니다.
Socket은 서로 다른 호스트 간의 프로세스 간 양방향 통신을 위한 엔드포인트로 간주됩니다. 간단히 말하면, 소켓의 관련 기능을 사용하여 통신 프로세스를 완료하는 것입니다. . 소켓은 애플리케이션과 네트워크 드라이버 사이의 브리지입니다. 소켓은 애플리케이션에서 생성되고 바인딩을 통해 네트워크 드라이버와의 관계를 설정합니다. 그 후 애플리케이션이 소켓으로 보낸 데이터는 소켓에 의해 네트워크 드라이버로 전달되어 네트워크로 전송됩니다. 컴퓨터가 소켓에 바인딩된 IP 주소 및 포트 번호와 관련된 데이터를 네트워크로부터 수신한 후, 네트워크 드라이버는 이를 소켓에 전달하고, 애플리케이션은 수신된 데이터를 소켓에서 추출할 수 있습니다. 네트워크 애플리케이션은 이런 방식으로 이루어집니다. , 데이터는 소켓을 통해 송수신됩니다.
운영 체제는 네트워크 통신과 서로 다른 애플리케이션 프로세스 간의 연결을 구별합니다. 세 가지 주요 매개변수는 통신의 대상 IP 주소, 사용된 전송 계층 프로토콜(TCP 또는 UDP) 및 사용된 포트 번호입니다.
套接字连接的过程如同(客户)打一个电话到一个大公司,接线员(服务器进程)接听电话并把它转接到你要找的部门,然后再从那里转到你要找的人(服务器套接字),然后接线员(服务器进程)再继续转接其它(客户)的电话。
套接字有本地套接字和网络套接字两种。本地套接字的名字是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视频教程》
위 내용은 리눅스 소켓 파일이란 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!