Jesse's home


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

34.Python之路 - 网络编程初识

发表于 2020-06-26 | 分类于 python , 05-Network |

Python之路 - 网络编程初识

前言 🍀

在互联网没有诞生之前 , 我们都是在自己的计算机上自娱自乐 , 那时候的程序也都是单机版的程序 , 随后互联网诞生了 , 用网络把各个计算机连接到了一起 , 让处在网络中的计算机可以互相通信 , 网络编程就是如何在程序中实现两台计算机之间的通信

最基本的例子莫过于我们传输文件了 , 没有网络的情况下我们只能利用U盘或者硬盘 , 先从我的计算机上将要传输的文件写入到我们的U盘或者硬盘 , 然后再用已有文件的U盘或者硬盘写入其他计算机 , 这样的局限性有多大可想而知 ; 利用网络我们可以直接十万八千里进行文件传输 , 比如用我的QQ传文件给你的QQ , 当然这个例子可能不怎么好 , 因为你传文件一般可能不会用QQ来传

阅读全文 »

35.Python之路 - 网络编程之Socket

发表于 2020-06-26 | 分类于 python , 05-Network |

Python之路 - 网络编程之Socket

C/S架构 🍀

在网络通信中 , 一般是一方求一方应 , 求的一方就是客户端即 Client , 应的一方就是服务端即Server , 这就是C/S架构 , 在互联网中处处是C/S架构 , 比如我们访问百度 , 百度就是一个服务端 , 而我们的浏览器就是一个客户端

Socket 🍀

Socket是应用层与TCP/IP协议族通信的中间软件抽象层 , 它是一组接口 , 是从顶上三层 (osi七层协议的应用层) 进入传输层的接口 ; 顶上三层通常构成所谓的用户进程 , 底下四层却通常作为操作系统内核的一个部分提供

Socket又叫做套接字 , Python中socket为我们封装好了TCP/UDP协议 , 所以我们无需深入理解 , 只要遵循socket的规定去编程就可以了

创建socket对象

创建socket对象就是一个建立TCP的过程 , 即三次握手 , 断开当然就是四次挥手了

阅读全文 »

36.Python之路 - Socket实现QQ聊天

发表于 2020-06-26 | 分类于 python , 05-Network |

Python之路 - Socket实现QQ聊天

介绍 🍀

在上一篇中写了最基本版的socket服务端和客户端 , 即仅能通信一次后就自动关闭了 , 显然实际应用中可不是这样的 , 那就来写一个像QQ一样的聊天程序吧

TCP实现 🍀

因为TCP是有链接的 , 这就导致只能有一个服务端 , 但是可以有多个客户端

tcpqq_server.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import socket
sock = socket.socket()
sock.bind(('127.0.0.1', 8080))
sock.listen(5)
# 实现链接循环
while True:
print("Watiting for the link...")
conn, addr = sock.accept()
print("Your friend {} is online...".format(addr))
# 实现通信循环
while True:
messages = conn.recv(1024)
print("Messages from [{}]:{}".format(addr, messages.decode('utf-8')))
if messages == b'q':
break
else:
while True:
data = input("Please input the messages to be sent:").strip().encode('utf-8')
# 注意发送的内容不能为空,否则接收方就会一直等下去
if not data:
print("Can't be empty...")
continue
conn.send(data)
break
print("Your friend {} is offline...".format(addr))
conn.close()
sock.close()

tcpqq_client.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import socket
sock = socket.socket()
sock.connect(('127.0.0.1', 8080))
# 实现通信循环
while True:
messages = input("Please input your messages to be sent:").strip().encode('utf-8')
# 注意发送的内容不能为空,否则接收方就会一直等下去
if not messages:
print("Can't be empty...")
continue
elif messages == b'q':
break
else:
sock.send(messages)
data = sock.recv(1024)
print("Messages from [{}]:{}".format(('127.0.0.1', 8080), data.decode('utf-8')))
sock.close()
阅读全文 »

30.Python之路 - 特殊成员方法

发表于 2020-06-26 | 分类于 python , 04-Object-Oriented |

Python之路 - 特殊成员方法

__doc__ 🍀

查看类的描述信息

1
2
3
4
5
6
7
8
class Foo:
"""
这是一个类,什么都没有的类
"""
def __init__(self):
pass
print(Foo.__doc__)
# 执行结果: 这是一个类,什么都没有的类

__module__ 🍀

查看当前操作对象位于哪个模块

1
2
3
4
# my_module.py
class Foo:
def __init__(self):
pass
1
2
3
4
# test.py
from my_module import Foo
print(Foo.__module__)
# 执行结果: my_module

__class__ 🍀

查看对象的类

阅读全文 »

37.Python之路 - Socket实现远程执行命令

发表于 2020-06-26 | 分类于 python , 05-Network |

Python之路 - Socket实现远程执行命令

os模块实现 🍀

osssh_server.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 导入socket模块
import socket
# 导入os模块
import os
# 创建套接字对象
sock = socket.socket()
# 重置ip和端口
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定ip和端口
sock.bind(('127.0.0.1', 8080))
# 监听
sock.listen(5)
# 链接循环
while True:
print("Waitting for connection...")
# 阻塞
conn, addr = sock.accept()
print("{}successful connection...".format(addr))
while True:
cmd = conn.recv(1024)
# 接收为空说明客户端断开了连接
if not cmd:
print("Client is disconnected...")
break
print("The command is {}".format(cmd.decode()))
# 利用os模块进行系统调用,py3中popen参数为str,所以先decode
data = os.popen(cmd.decode()).read()
# 发送命令执行结果
conn.send(data.encode('utf-8'))
# 关闭链接
conn.close()
# 关闭套接字
sock.close()

osssh_client.py

阅读全文 »

38.Python之路 - 网络编程之粘包

发表于 2020-06-26 | 分类于 python , 05-Network |

Python之路 - 网络编程之粘包

粘包 🍀

由上一篇<Python之路 - Socket实现远程执行命令>中所出现的问题引出了粘包这个问题 , 粘包到底是什么?

首先 , 粘包现象只出现在TCP中 , 为什么说只有在TCP中才会发生粘包现象 , 先来详细解释一下TCP与UDP吧

TCP

TCP (transprot control protocol, 传输控制协议) 是面向连接的 , 面向流的 , 提供高可靠性服务 . 收发两端都有要一一对应的socket(一对一模式) , 因此发送端为了将多个发往接收端的包 , 更有效的发到对方 , 使用了优化方法(Nagle算法) , 将多次间隔较小且数据量小的数据 , 合并成一个大的数据块 , 然后进行封包 . 必须提供科学的拆包机制 , 才能进行合理的分辨 , 所以说面向流的通信是无消息保护边界的

UDP

UDP(user datagram protocol, 用户数据报协议) 是无连接的 , 面向消息的 , 提供高效率服务 . 不使用块的合并优化算法 , 由于UDP支持的是一对多的模式 , 所以接收端的skbuff (套接字缓冲区) 采用了链式结构来记录每一个到达的UDP包 , 在每个UDP包中就有了消息头 (消息来源地址 , 端口等信息) , 这样 , 对于接收端来说 , 就容易进行区分处理了 . 即面向的通信是有消息保护边界的

区别

TCP是基于数据流的 , 于是收发的消息不能为空 , 这就需要在客户端和服务端都添加空消息的处理机制 , 防止程序卡住 , 而UDP是基于数据报的 , 就算收发空内容 , 也不是空消息 , UDP协议会自动帮你封装上消息头

阅读全文 »

39.Python之路 - Socketserver实现多并发

发表于 2020-06-26 | 分类于 python , 05-Network |

Python之路 - Socketserver实现多并发

阅读指引 🍀

在上面的整理篇章中 , 简单的网络编程基本已经会了 , 一个TCP , 一个UDP , 然后就是粘包问题

但是在上述中有一个问题 , 在现实生活中 , 一个服务端肯定常常需要同时服务好几个客户端 , 而上述篇章中并没有实现一对多同时进行的情况 , TCP中只能等前一个链接断开后续的才能连上 , 没连上就一直等 ; UDP则是接一次发一次 , 并不能同时接两次发两次 . 为了处理这个问题 , 即实现并发 (后续文章详细讲解) , Python中有一个socketserver模块可以满足我们的要求

socketserver 🍀

Python提供了两个级别访问的网络服务:

  1. 低级别的网络服务支持基本的socket , 它提供了标准的BSD Socket API , 可以访问底层操作系统Socket接口的全部方法
  2. 高级别的网络服务模块socketserver , 它提供了服务器中心类 , 可以简化网络服务器的开发

socket就不用说了 , now socketserver

我们知道基于TCP的套接字 , 关键就是两个循环 , 一个链接循环(多人) , 一个通信循环(多消息)

在socketserver模块中分为两大类 : server类 (解决链接问题) 和request类 (解决通信问题)

如果想进一步了解 , 可以看看官方文档 , < socketserver官方文档 >

阅读全文 »

41.Python之路 - 多线程编程

发表于 2020-06-26 | 分类于 python , 06-Concurrent |

Python之路 - 多线程编程

前言 🍀

在上一篇中说了一大堆理论 , 那么现在就开始实践了

先说线程再说进程 , 为什么 ? 因为在Python中有一个Python GIL全局解释器锁 , 这是个什么东西? 最后来说

总之线程和进程都是与操作系统有关的知识 , 所以操作系统基础 , 对于这两节内容的理解会有很大的帮助

Threading 🍀

Python通过两个标准库_thread (built-in) 和threading提供对线程的支持 , threading对_thread进行了封装

1
2
3
4
5
_thread.py
'''
This module provides primitive operations to write multi-threaded programs.
The 'threading' module provides a more convenient interface.
'''

So , 明显我们一般直接使用threading

threading模块中提供了Thread , Lock , RLock , Semaphore , Event , Condition , Timer等组件

阅读全文 »

42.Python之路 - 多进程编程

发表于 2020-06-26 | 分类于 python , 06-Concurrent |

Python之路 - 多进程编程

前言 🍀

上一篇《多线程编程》中已经对Python中多线程部分进行了整理 , 进程中有很多也是相似的

概念在并发编程第一篇中就已经介绍了 , So直接开始操作

multiprocessing 🍀

从上一篇我们也已经知道了 , Python中的多线程无法利用多核优势 , 所以如果我们想要充分地使用多核CPU的资源 , 那么就只能靠多进程了 , 因为进程是系统调度的 , Python提供了multiprocessing模块了对多进程的支持

multiprocessing模块中提供了Process , Queue , Pipe , Lock , RLock , Event , Condition等组件 , 与threading模块有很多相似之处

Process 🍀

用于创建进程的类 , 与threading模块中的_Thread类类似

1
2
3
4
'''
Process类的构造函数
def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
'''

参数说明

参数 说明
group 未使用 , 值始终
target 与threading.Tread中的target参数一样 , 表示调用对象 , 即子进程要执行的任务
name 子进程的名称
args 传入target函数中的位置参数 , 是一个元组 , 与线程一样 , 参数后必须加逗号
kwargs 表示调用对象的字典

方法说明

方法 说明
Process.run (self) 进程启动时运行的方法 , 由该方法调用target参数所指定的函数 , 在子类中可以进行重构 , 与线程中一样
Process.start (self) 启动进程 , start方法就是去帮你调用run方法
Process.terminate (self) 强制终止进程 , 不会进行任何清理操作 , 使用时需小心其子进程与锁的问题
Process.join (self, timeout=None) 与线程中一样 , 阻塞调用 , 主进程进行等待 , timeout为超时时间
Process.is_alive (self) 判断进程是否正在运行 , 返回bool值

实例属性说明

属性 说明
Process.daemon 默认值为False , True则为守护进程
Process.name 进程的名称
Process.pid 进程的pid
Process.exitcode 进程运行时为None , 如果为-N , 表示被信号N结束
Process.authkey 进程的身份验证键 , 默认是由os.urandom()随机生成的32字符的字符串 . 这个键的用途是为涉及网络连接的底层进程间通信提供安全性 , 这类连接只有在具有相同的身份验证键时才能成功
阅读全文 »

40.Python之路 - 进程与线程

发表于 2020-06-26 | 分类于 python , 06-Concurrent |

Python之路 - 进程与线程

前言 🍀

进程与线程是操作系统中的概念 , 这也是操作系统中最核心的概念

进程 🍀

进程是对正在运行程序的一个抽象 , 即一个进程就是一个正在执行程序的实例

从概念上说 , 每个进程拥有它自己的虚拟CPU . 当然 , 实际上真正的CPU在各进程之间来回切换 . 这种快速切换就是多道程序设计 . 但是某一瞬间 , CPU只能运行一个进程 , 但在1秒钟期间 , 它可能运行多个进程 , 就是CPU在进行快速切换 , 有时人们所说的 伪并行 就是指这种情形

创建进程 🍀

操作系统中 , 有4种事件导致进程的创建

  1. 系统初始化 , 启动操作系统时 , 通常会创建若干个进程 , 分为前台进程和后台进程
  2. 执行了正在运行的进程所调用的进程创建系统调用
  3. 用户请求创建一个新的进程
  4. 一个批处理作业的初始化

从技术上看 , 在所有这些情况中 , 新进程都是由一个已存在的进程执行了一个用于创建进程的系统调用而创建的 . 这个进程可以是一个运行的用户进程 , 一个由键盘或鼠标启动的系统进程或者一个批处理管理进程 . 这个进程所做的工作是 , 执行一个用来创建新进程的系统调用 . 在Linux/Unix中提供了一个fork() 系统调用就是用来创建进程的 (子进程) , 当然在Windows中也有相对应的系统调用

阅读全文 »
1…91011…21
Jesse

Jesse

求知若饥,虚心若愚.

209 日志
44 分类
41 标签
RSS
© Tue Jun 12 2018 08:00:00 GMT+0800 (GMT+08:00) — 2021 Jesse