首页 > 编程语言 >网络编程之socket模块

网络编程之socket模块

时间:2022-11-16 18:58:06浏览次数:43  
标签:socket 编程 sock TCP server 模块 服务端 客户端

网络编程之socket模块

在上一篇博文中,我们介绍了osi的七层协议,从物理层简单介绍到了传输层,说到了传输层。

每一层都有相对要遵循的协议如图:

img

其中,物理层就是二进制,应用层可能遵循的协议太多了,有html等。

传输层之tcp与udp协议

TCP与UDP都是用来规定通信方式的。

tcp协议

又称可靠协议(数据不容易丢失)

三次握手

image

客户端发送连接请求,服务端接收到了并反馈接收可以建立从客户端到服务端的通道,与此同时,服务端可以发送连接请求,让客户端同意服务端向客户端建立通道,这样就建立了双向通道。

虽然但是,造成数据不容易丢失的原因不是因为有双向通道,而是因为有反馈机制。

给对方发送数据的时候,会保留一个副本,直到对方回应收到了消息,才会删除本地数据,否则会在一定时间内反复的发送。

  • 三次握手后成功建立连接,连接双方就能通过双向通道发送数据了

  • 洪水攻击

    同一时间有大量的客户端请求建立链接,会导致服务端一致处于SYN_RCVD状态

  • 服务端如何区分客户端建立链接的请求

    可以对请求做唯一标识,如它的IP地址等

四次挥手

image

  1. 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。

  2. 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。

    注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。

  3. 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。

  4. 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。

udp协议

也称之为数据报协议和不可靠协议,没有什么反馈机制,一端发送了数据后就不管了,另外一端能不能收到数据不会影响发送端只发一次。

qq最初就是使用最基本的udp协议来传输消息。

而现在还是用udp,只是添加了很多功能来保障数据的安全。

socket模块

Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

img

简而言之,socket帮我们把传输层及以下的处理全做了,调这个模块就能帮助我们通过网络完成两个程序间的通讯。

socket代码实现

# 服务端
import socket

# 1.产生一个socket对象并指定采用的通信版本和协议(TCP)
server = socket.socket()  # 括号内不写参数 默认就是TCP协议  family=AF_INET基于网络的套接字 type=SOCK_STREAM流式协议即TCP
# 2.绑定一个固定的地址(服务端必备的条件)
server.bind(('127.0.0.1', 8080))  # 127.0.0.1为本地回环地址 只有自己的电脑可以访问
# 3.设立半连接池(暂且忽略)
server.listen(5)
# 4.等待接客
sock, addr = server.accept()  # return sock, addr  三次握手
print(sock, addr)  # sock就是双向通道 addr就是客户端地址
# 5.服务客人
data = sock.recv(1024)  # 接收客户端发送过来的消息 1024字节
print(data.decode('utf8'))
sock.send('我是服务端~诶嘿'.encode('utf8'))  # 给客户端发送消息 注意消息必须是bytes类型
# 6.关闭双向通道
sock.close()  # 四次挥手
# 7.关闭服务端
server.close()  # 关闭服务端(一般不用)



# 客户端
import socket

# 1.生成socket对象指定类型和协议
client = socket.socket()
# 2.通过服务端的地址链接服务端
client.connect(('127.0.0.1', 8080))
# 3.直接给服务端发送消息
client.send('我是客户端~哦吼'.encode('utf8'))
# 4.接收服务端发送过来的消息
data = client.recv(1024)
print(data.decode('utf8'))
# 5.断开与服务端的链接
client.close()

socket代码简要优化

1.聊天内容自定义
	针对消息采用input获取
2.让聊天循环起来
	将聊天的部分用循环包起来
3.用户输入的消息不能为空
	本质其实是两边不能都是recv或者send,一定是一方收一方发 
    在win中如果发空,会报错
4.服务端多次重启可能会报错
	Address already in use 主要是mac电脑会报
  	我们可以通过改端口号的方式(服务端的bind和客户端connect都要改)来简单解决端口占用的问题
5.当客户端异常断开的情况下 如何让服务端继续服务其他客人
	windows服务端会直接报错,mac服务端会有一段时间反复接收空消息延迟报错	
  	处理方式:异常处理、空消息判断

半连接池

server.listen(5)  # 半连接池

在服务端的程序中,我们的server对象可以通过这一句代码来监听有哪些程序尝试连接我们的服务端程序,当服务端正和某个客户端建立好通道进行联系时,其他的客户端就得排队了,当服务端断开与之前客户端的联系,新的客户端就可以与服务端进行连接了(前提是服务端还有accept进行回应)

如:

# 服务端
import socket

server = socket.socket()
server.bind(('127.0.0.1', 8888))
server.listen(5)

while True:
    # 每次循环开始都可以接收一次连接
    sock, addr = server.accept()
    print(f'{addr}已接入')
    # 模拟对话开始
    bytes_msg = sock.recv(1024)
    print(bytes_msg.decode('utf8'))
    sock.send('服务端向你扔了一只小狗'.encode('utf8'))
    # 模拟对话结束
    
# 客户端
import socket

client = socket.socket()
client.connect(('127.0.0.1', 8888))
anyone = input('扔一只什么给服务端吧:')
client.send(f'扔了只{anyone}'.encode('utf8'))
print(client.recv(1024).decode('utf8'))

在上述程序中,我们通过客户端不断的向服务端发起请求,交流会话。

image

将这个打开,就可以让客户端程序同时开启多个,当我们发起6个以上的客户端连接请求,第一个正在于服务端对话,而后面五个在半连接池中等待,再由客户端在此时想要向我们发送这个端口发送请求就会连接异常。

所以这个listen中的数字就表示可以容纳的等待连接数量。

image

标签:socket,编程,sock,TCP,server,模块,服务端,客户端
From: https://www.cnblogs.com/Leethon-lizhilog/p/16897119.html

相关文章

  • SparkSQL 核心编程
    DataFrame创建DataFrame从Spark数据源进行创建➢查看Spark支持创建文件的数据源格式scala>spark.read.csvformatjdbcjsonloadoptionoptionsorcparqu......
  • C /S 架构——socke模块
    C/S架构——socke模块一、socket概念如果我们需要编写基于网络进行数据交互的程序意味着我们需要自己通过代码来控制我们之前所学习的OSI七层(很繁琐很复杂类似于我......
  • OSI七层协议补充与socket套节字
    OSI七层协议补充与socket套节字一、传输层之TCP与UDP协议TCP与UDP协议都是用来规定通信方式的,数据传输过程中能够遵循的协议有很多其中TCP协议和UDP协议是较为常见的两......
  • Python实验报告——第8章 模块
    Python实验报告——第8章模块 实验报告【实验目的】 1.掌握Python内置的标准模块和第三方模块的使用。【实验条件】1.PC机或者远程编程环境。 【实验内容......
  • 第11章 面向对象编程:继承(笔记)
    11.1简介为了复用11.2基类和派生类父类与子类11.3基类和派生类之间的关系11.4派生类中的构造函数和析构函数11.5public、protected、private继承权限11.6继承......
  • 第12章 面向对象编程:多态性
    12.1简介程序通用化12.2多态性介绍:多态视频游戏12.3类继承层次中对象之间的关系12.4类型域和switch语句12.5抽象类和纯virtual函数跟一个表格有关12.6实例研究......
  • python JSON模块
    一、JSON介绍JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,易于人阅读和编写。二、常用方法方法描述json.loads()将JSON字符串转化为Python对......
  • 网络编程
    网络编程2目录网络编程2传输层之TCP与UDP协议1.TCP与UDP协议2.TCP协议3.TCP协议--三次握手4.TCP协议--四次挥手5.UDP协议6.TCP协议vsUDP协议应用层socket套接字编程半......
  • 结对编程 电梯调度
    《软件工程基础》上机实验报告撰写要求 一、 纸张与页面要求1. 采用国际标准A4型打印纸或复印纸,纵向打印。2. 封页和页面按照下面模板书写(正文为:小四宋体1.5倍行......
  • 构造Socket
    1:Socket的构造函数​​Socket​​()​​Socket​​(​​InetAddress​​ address,int port)​​Socket​​(​​InetAddress​​ address,int port,​​InetAddress......