首页 > 编程语言 >网络编程之Socket抽象层

网络编程之Socket抽象层

时间:2024-01-16 21:14:34浏览次数:26  
标签:Socket 编程 TCP 地址 抽象 接字 port socket

Socket介绍

假设我们需要编写一个C/S架构的程序,实现数据交互,就需要使用到OSI七层协议,由于它的缺点是分层太多,增加了网络工作的复杂性,所以没有大规模应用。后来人们对 OSI 进行了简化,合并了一些层,最终只保留了 4 层,从下到上分别是接口层、网络层、传输层和应用层,这就是 TCP/IP 模型。

image

而socket(套接字)是在应用程序的传输层和应用层之间抽象出了一个层叫做socket抽象层,可以理解为TCP/IP协议栈提供的对外的操作接口,即应用层通过网络协议进行通信的接口。Socket其实就是一个门面,它把复杂的TCP/IP协议族隐藏在Socket接口后面,不需要自己处理每一层。

image

什么是Socket

  • Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
    • 在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面
    • 对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
  • 所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的。
  • 也有人将socket说成ip+port
    • ip是用来标识互联网中的一台主机的位置
    • 而port是用来标识这台机器上的一个应用程序
    • ip地址是配置到网卡上的
    • 而port是应用程序开启的
    • ip与port的绑定就标识了互联网中独一无二的一个应用程序
  • 而程序的pid是同一台机器上不同进程或者线程的标识

套接字分类

(1) 基于文件类型的套接字家族

套接字家族的名字:AF_UNIX

unix一切皆文件,基于文件的套接字调用的就是底层的文件系统来取数据,两个套接字进程运行在同一机器,
可以通过访问同一个文件系统间接完成通信

(2) 基于网络类型的套接字家族

套接字家族的名字:AF_INET

AF_INET(又称 PF_INET)是 IPv4 网络协议的套接字类型,AF_INET6 则是 IPv6 的
还有一些其他的地址家族,不过,他们要么是只用于某个平台,要么就是已经被废弃,很少被使用,或者是根本没有实现,所有地址家族中,AF_INET是使用最广泛的一个,python支持很多种地址家族,但是由于我们只关心网络编程,所以大部分时候我么只使用AF_INET

Socket套接字使用

套接字Socket可以使用不同的网络协议进行端对端的通信,主要是TCP和UDP协议,使用的流程如下图所示

image

Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

如何创建套接字

套接字 Socket 实质上提供了主机间进程通信的连接点。进程通信之前,双方首先必须各自创建一个连接点。否则是没有办法建立联系并相互通信的。Python 中,我们用 socket() 函数来创建套接字,语法格式如下:

  import socket
  socket.socket(socket_family,socket_type,protocal=0)
  socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。
  
 # 获取tcp/ip套接字
  tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  
 # 获取udp/ip套接字
  udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

 # 由于 socket 模块中有太多的属性。我们在这里破例使用了'from module import *'语句。使用 'from socket import *',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,这样能 大幅减短我们的代码。
 

Socket 对象(内建)方法

函数 描述
服务器端套接字
s.bind() 绑定地址(host,port)到套接字, 在AF_INET下,以元组(host,port)的形式表示地址。
s.listen() 开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。
s.accept() 被动接受TCP客户端连接,(阻塞式)等待连接的到来
客户端套接字
s.connect() 主动初始化TCP服务器连接,。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex() connect()函数的扩展版本,出错时返回出错码,而不是抛出异常
公共用途的套接字函数
s.recv() 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
s.send() 发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall() 完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
s.recvfrom() 接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
s.sendto() 发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。
s.close() 关闭套接字
s.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
s.getsockname() 返回套接字自己的地址。通常是一个元组(ipaddr,port)
s.setsockopt(level,optname,value) 设置给定套接字选项的值。
s.getsockopt(level,optname[.buflen]) 返回套接字选项的值。
s.settimeout(timeout) 设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如connect())
s.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
s.fileno() 返回套接字的文件描述符。
s.setblocking(flag) 如果flag为0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用recv()没有发现任何数据,或send()调用无法立即发送数据,那么将引起socket.error异常。
s.makefile() 创建一个与该套接字相关连的文件

如何为套接字绑定主机及端口

一个完整的 Socket 可以用一个通信双方的相关描述:

   	协议 , 本地地址 , 本地端口 , 远程地址 , 远程端口 

实际应用中,在创建一个 Socket 时先用一个半相关描述(服务器这一半可以确定,而另一半尚不确定):

	协议 , 本地地址 , 本地端口 

每一个 Socket 有一个本地的唯一端口号,由操作系统分配。

绑定指为套接字绑定地址包含主机及其端口。 在 AF_INET 下,以元组(host,port)的形式表示地址。

  • host:用字符串表示主机的 IP 地址。表示本机'',也可用 127.0.0.1 表示回环地址,或者主机的一般 IP 地址。

  • port:端口号,数字表示。1024 以下为系统约定,自定义的用 1024 以上。

​ 绑定通过套接字的绑定方法 bind() 来完成,输入参数为元组 (host,port)。

绑定示例:

my_socket.bind(('127.0.0.1', 1234))         # 绑定本地回环地址
my_socket.bind(('', 1234))                  # 自动获取IP地址

如何设置套接字监听

服务器程序在调用创建套接字 socket() 和绑定 bind() 之后需要处于监听状态,因为不知客户端什么时候开始进行请求连接。为此,需调用套接字的监听方法 listen()。

一个服务端可能同时面对多个客户端的连接请求,为此服务器程序需创建一个连接队列来保存的连接请求,并依次为连接请求建立相应连接。为此需设置队列的大小作为监听方法的参数。

监听示例:

my_socket.listen(10)    # 设置连接队列大小为10,并使套接字处于监听状态。

标签:Socket,编程,TCP,地址,抽象,接字,port,socket
From: https://www.cnblogs.com/xiao01/p/17968528

相关文章

  • 网络编程之基于UDP协议的socket套接字编程
    基于UDP的套接字udp是无链接的,先启动哪一端都不会报错【1】方法简介(1)UDP服务端server=socket()#创建一个服务器的套接字server.bind()#绑定服务器套接字inf_loop:#服务器无限循环conn=server.recvfrom()/conn.sendto()#对话(接收与发送)serv......
  • 网络编程之粘包问题
    粘包问题只有TCP有粘包现象,UDP永远不会粘包什么是粘包存在于客户端接收数据时,不能一次性收取全部缓冲区中的数据.当下一次再有数据来时,缓冲区中剩余的数据会和新的数据'粘连'在一起.这就是粘包现象。##什么是粘包?存在于TCP/IP协议中数据粘连在一起。##socket中造成粘......
  • 网络编程之网络架构及其趋势
    一、网络结构模型C/S和B/S都是互联网中常见的网络结构模型。引言刚开始的时候用户去取数据,直接就去主机拿,从这里开始就分出了客户端和服务端。客户端:用户安装的软件;服务端:统一管理数据库的主机中的软件就叫做服务端,再后来服务端不只是管理数据,外加处理业务逻辑。1.1什么......
  • 网络编程TCP UDP
    网络编程(1)什么是网络编程网络编程是指通过编程语言在计算机之间建立通信的一种方式。它是在互联网上进行数据传输的关键组成部分,使计算机能够相互通信、交换信息和共享资源。网络编程涉及许多不同的技术和协议,包括TCP/IP(传输控制协议/因特网协议),HTTP(超文本传输协议),FTP(文件传......
  • socket模块
    socket(1)scoket层在哪(2)什么是socketSocket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。所......
  • springBoot通过AOP(面向切面编程)实现自动保存请求日志
    1.定义注解importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;@Target(ElementType.METHOD)//指定该注解只能应用于方法上@Retention(RetentionPolicy.......
  • 【6.0】socketserver实现并发
    【一】引入socket并不能多并发,只能支持一个用户socketserver模块是Python中用于创建网络服务器的模块,提供了一种简单而一致的接口。它是构建网络服务器的框架,处理了创建、维护和关闭连接的许多底层细节socketserver是socket的再封装。【二】socketserver介绍【1】简......
  • 网络编程
    【一】CS架构与BS架构C/S和B/S都是互联网中常见的网络结构模型。【1】什么是C/S模型C是英文单词“Client”的首字母,即客户端的意思C/S就是“Client/Server”的缩写,即“客户端/服务器”模式。例如:拼多多APP、PC上的有道云笔记等等【2】什么是B/S模型B是英文单词“B......
  • 【python网络编程相关】 ----操作系统相关了解
    title:【python网络编程相关】----操作系统相关了解date:2024-01-1615:54:06updated:2024-01-1616:20:00description:【python网络编程相关】----操作系统相关了解cover: https://www.cnblogs.com/YZL2333/p/10444200.htmlhttps://home.cnblogs.com/u/......
  • 以 Golang 为例详解 AST 抽象语法树
    前言各位同行有没有想过一件事,一个程序文件,比如hello.go是如何被编译器理解的,平常在编写程序时,IDE又是如何提供代码提示的。在这奥妙无穷的背后,AST(AbstractSyntaxTree)抽象语法树功不可没,他站在每一行程序的身后,默默无闻的工作,为繁荣的互联网世界立下了汗马功劳。AST抽象......