Linux网络编程(四)—— 套接字socket

本文深入解析套接字(socket)的概念,探讨其在TCP/IP通信中的关键作用,包括套接字的类型、工作原理以及在网络编程中的重要数据结构。涵盖了流式、数据报和原始套接字的特点,以及Linux下套接字的实现方式。
摘要由CSDN通过智能技术生成

套接字socket


前面的文章中,我们讲了TCP/IP、TCP和UDP的一些基本知识,但是协议只有一套,而我们系统多个TCP连接或多个应用程序进程必须通过同一个 TCP协议端口传输数据。为了区别不同的应用程序进程和连接 ,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为 套接字(Socket)的接口
套接字就是支持TCP/IP网络通信的基本操作单元,是我们进行TCP/IP进行通信的接口。

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

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

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

	*Socket=Ipaddress+TCP/UDP+port*

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

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

套接字有本地套接字和网络套接字两种。

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

套接字类型


TCP/IP中有三种常用的套接字

流式套接字(SOCK_STREAM)

流式套接字提供可靠的、面向连接的通信流,保证数据传输的可靠性和按序收发。TCP通信的使用的就是流式套接字。

数据报套接字(SOCK_DGRAM)

数据包套接字实现了一种不可靠、无连接的服务。数据通过相互独立的报文进行传输,是无序的,并且不保证可靠的传输。UDP受用的就是数据报套接字。

原始套接字(SOCK_RAW)

原始套接字允许对底层(如IP或ICMP)进行直接访问,它功能强大但使用较为不便,主要用于一些协议的开发。

原始套接字与标准套接字(标准套接字指的是前面介绍的流套接字和数据报套接字)的区别在于:原始套接字可以读写内核没有处理的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;
};
  • state用于表示socket所处的状态,是一个枚举变量,该成员只对TCP socket有用,因为只有TCP是面向连接的协议,UDP跟raw不需要维护socket状态。
    其类型定义如下:

     typedef enum {
           
        SS_FREE = 0,            //该socket还未分配  
        SS_UNCONNECTED,         //未连向任何socket  
        SS_CONNECTING,          //正在连接过程中  
        SS_CONNECTED,           //已连向一个socket  
        SS_DISCONNECTING        //正在断开连接的过程中  
    }socket_state;  
    
  • flags是一组标志位,在内核中并没有发现被使用。

  • ops是协议相关的一组操作集,结构体struct proto_ops的定义如下:

    struct proto_ops {
           
        int     family;  
        struct module   *owner;  
        int (*release)(struct socket *sock);  
        int (*bind)(struct socket *sock, struct sockaddr *myaddr, int sockaddr_len);  
       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值