TCP协议

TCP是传输控制协议,建立双向通道。

三次握手,建立连接

  • 客户端向服务端发送建立连接的请求
  • 服务端接收请求返回确认信息给客户端,并向客户端发送建立连接的请求
  • 客户端接收请求返回确认信息给服务端

反馈机制:一次请求必须有一次响应。即收到请求后,必须告知对方已收到请求。

四次挥手,断开连接

  • 客户端向服务端发送断开连接的请求
  • 服务端接收请求返回确认信息发给客户端
  • 服务端确认所有数据接收完毕以后,发送断开连接的请求给客户端
  • 客户端接收请求返回确认信息给服务端

socket套接字通信

定义:python内置的模块,又称套接字,用来封装互联网协议(应用层以下的层)

作用:实现互联网协议应用层以下的工作,提高开发效率

使用方式:见代码

  • 服务端server.py
import socket

# 获取socket 对象
server = socket.socket()
# 绑定服务端ip 地址和端口
# 127.0.0.1是回环地址,表示本机ip
server.bind(('127.0.0.1', 8080))
# 半连接池,表示可以同时让多少个客户端访问。
# 一个客户端正在交互,剩下的等待交互,listen(n):n+1个客户端
server.listen(5)
# 阻塞,直到客户端访问,返回连接请求和客户端IP
conn, client = server.accept()
# 接收客户端发送的信息并打印
# 接收默认最大字节数:1024(可根据内存自行调整)
client_data = conn.recv(1024).decode('utf-8')
print(f"来自客户端的消息:{client_data}")
# 向客户端发送消息
send_msg = input("请输入指令>>>>>:").strip().encode('utf-8')
conn.send(send_msg) # 关闭连接
conn.close()
# 关闭服务
server.close()
  • 客户端client.py
import socket

# 创建socket对象
client = socket.socket()
# 向服务端请求连接
client.connect(('127.0.0.1', 9527))
# 向服务端发送数据,send只接收二进制数据
client_msg = input("请输入要发送给服务端的信息>>>>:").strip()
client.send(client_msg.encode('utf-8'))
# 接收服务端返回的数据
# 接收默认最大字节数:1024(可根据内存自行调整)
client_data = client.recv(1024).decode('utf-8')
print(f"来自服务端的消息:{client_data}")
# 关闭连接
client.close()

注意:

  • 先启动服务端,再启动客户端
  • 一次数据请求必须有一次响应,服务端和客户端不能同时发送请求或同时接收请求

粘包现象

  • 现象一:数据多次发送时间间隔短,且量少时,接送一次读取了信息,后续读取记录为空
# 客户端.py
import socket server = socket.socket()
server.connect(("127.0.0.1", 9527)) # 连续发送
server.send(b"hello")
server.send(b"hello")
server.send(b"hello") server.close()
# 服务端.py
import socket
from socket import SOL_SOCKET
from socket import SO_REUSEADDR server = socket.socket()
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server.bind(("127.0.0.1", 9527))
server.listen(5)
conn, client = server.accept() data1 = conn.recv(1024)
data2 = conn.recv(1024)
data3 = conn.recv(1024) print(data1)
print(data2)
print(data3) conn.close()
server.close()

输出结果

b'hellohellohello'
b''
b''
  • 现象二:当发送数据的字节数超出每次接收的最大限制数,会将上次没有接收完的记录在下次接收
# 客户端.py
import socket client = socket.socket()
client.connect(('127.0.0.1', 9527))
client.send(b'hello world!')
client.send(b'lift is smart!')
client.close()
# 服务端.py
import socket
from socket import SOL_SOCKET
from socket import SO_REUSEADDR server = socket.socket()
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 9527))
server.listen(5) conn, client = server.accept() re_data1 = conn.recv(5).decode('utf-8')
re_data2 = conn.recv(5).decode('utf-8') print(re_data1)
print(re_data2)
conn.close()
server.close()

输出结果

hello
worl

struct模块—解决粘包问题

定义:python内置的模块,可以将 固定长度的数据,打包成固定格式的长度

作用:将真实数据,做成一个固定长度的报头,客户端发送给服务端,服务端可以接收报头(反之亦然)。然后对报头进行解包,获取真实数据的长度,进行接收即可。

使用,以现象二举例(实质都一样解决)

# 客户端.py
import socket
import struct client = socket.socket()
client.connect(('127.0.0.1', 9527))
msg1 = 'hello world!'
# 使用struct模块中的pack方法,模式‘i’表示4个字节
# 将要发送的数据长度打包成一个header
header1 = struct.pack('i', len(msg1))
# 先将报头发送给服务端
client.send(header1)
# 再将真实数据发送给服务端
client.send(msg1.encode('utf-8'))
# 服务端.py
import socket
import struct server = socket.socket()
server.bind(('127.0.0.1', 9527))
server.listen(5)
conn, client = server.accept() # 读取报头
header = conn.recv(4)
# 使用struct.unpack 解析真实数据长度
header_len = struct.unpack('i', header)[0] # 读取真实数据
re_data = conn.recv(header_len) print(re_data.decode('utf-8'))
conn.close()
server.close()

python基础-网络编程part02的更多相关文章

  1. python 基础网络编程2

    python 基础网络编程2 前一篇讲了socketserver.py中BaseServer类, 下面介绍下TCPServer和UDPServer class TCPServer(BaseServer ...

  2. python 基础网络编程1

    python 基础网络编程1 Source code: Lib/socketserver.py lib的主目录下有一个sockserver.py文件, 里面是python基本的网络编程模型 共有一个b ...

  3. python基础网络编程--转

    python之网络编程 本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的 ...

  4. python基础-网络编程part01

    软件开发架构 C/S(Client / Server) 架构 概念:是一种软件系统体系结构.Client是客户端,Server是服务端.客户端需要安装专用的客户端软件. 比如:微信.QQ.王者荣耀等应 ...

  5. Python基础-网络编程request使用

    import requests#get请求 url = "http://127.0.0.1:8000/login" data={"username":" ...

  6. python之网络编程

    本地的进程间通信(IPC)有很多种方式,但可以总结为下面4类: 消息传递(管道.FIFO.消息队列) 同步(互斥量.条件变量.读写锁.文件和写记录锁.信号量) 共享内存(匿名的和具名的) 远程过程调用 ...

  7. Python高级网络编程系列之第一篇

    在上一篇中我们简单的说了一下Python中网络编程的基础知识(相关API就不解释了),其中还有什么细节的知识点没有进行说明,如什么是TCP/IP协议有几种状态,什么是TCP三次握手,什么是TCP四次握 ...

  8. python基础-函数式编程

    python基础-函数式编程  高阶函数:map , reduce ,filter,sorted 匿名函数:  lambda  1.1函数式编程 面向过程编程:我们通过把大段代码拆成函数,通过一层一层 ...

  9. python基础——面向对象编程

    python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...

随机推荐

  1. 【原创】从零开始搭建Electron+Vue+Webpack项目框架,一套代码,同时构建客户端、web端(二)

    摘要:上篇文章说到了如何新建工程,并启动一个最简单的Electron应用.“跑起来”了Electron,那就接着把Vue“跑起来”吧.有一点需要说明的是,webpack是贯穿这个系列始终的,我也是本着 ...

  2. Android H5混合开发(1):构建Cordova 项目

    Cordova是什么 Apache Cordova是一个开源的移动开发框架.允许你用标准的web技术-HTML5,CSS3和JavaScript做跨平台开发. 以移动平台为例,安卓.IOS平台设备的常 ...

  3. Docker应用部署

    MySQL: #拉取mysql镜像 docker pull centos/mysql--centos7 #创建容器 #-p 端口映射 -e添加环境变量MYSQL_ROOT_PASSWORD 是root ...

  4. Splash的使用

    Splash Lua脚本http://localhost:8050 入口及返回值 function main(splash, args) splash:go("http://www.baid ...

  5. Linux 如何创建或删除以横杠(-)开头的文件或目录

    小测试: [root@test test]# ls [root@test test]# touch -abc touch: invalid option -- 'b' Try `touch --hel ...

  6. windows系统一台电脑先后添加多个git账号

    概述 电脑上已经配置了github的ssh连接.现在又有一个不同的git账户,也就是要在一台电脑上配置两个git账号. 下面记录一下我配置的方法. 一.取消git全局配置 之前配置github的时候, ...

  7. Maven配置setting.xml详细说明

    <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="http://mav ...

  8. 那些Java架构师必知必会的技术

    Java基础 Java 7 和 Java 8 中的 HashMap原理解析 Java7 和 Java8 中的 ConcurrentHashMap 原理解析 Java中自定义注解 Java函数式编程和l ...

  9. 微信小程序如何解析html内容

    最近项目上遇到在微信小程序里需要显示新闻内容,新闻内容是通过接口读取的服务器中的富文本内容,是html格式的,小程序默认是不支持html格式的内容显示的,那我们需要显示html内容的时候,就可以通过w ...

  10. Python实现定时发送邮件代码

    mailtools.py代码如下: # -*- coding: utf-8 -*- #!/usr/bin/env python # @Time : 2017/12/22 17:50 # @Desc : ...