#coding utf-8
import socket全双工
socket.AF_INET #IPv4版本
socket.SOCK_DGRAM #是udp
socket.SOCK_STREAM #是tcp
#设置当服务器先close 保证下次运行程序可以立即使用端口
.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
3次握手操作
- 客户端发起链接syn
- 服务器回应ack并发起syn
- 客户端回应ack
4次挥手操作,一般由客户端发起关闭
- 客户端发起关闭‘发送’
- 服务器回应接收到
- 服务器发起关闭‘接收’
- 客户端回应接收到,并等待一段时间(2-5min)释放资源,又叫2msl两倍等待释放
udp不区分服务器与客户端
socket创建套接字
bind绑定IP和port
sendto/recvfrom发送/接收数据.recvfrom(1024)如果没有数据会造成阻塞
close关闭套接字tcp客户端
socket创建套接字
connect链接服务器
send/recv发送/接收数据
close关闭套接字tcp服务器
socket创建套接字
bind绑定IP和port
listen被动接收模式
accept接收客户端链接地址
recv/send接收/发送数据
close关闭套接字
.listen(128) 被动模式 128代表同一时间可以处理的链接数量
.accept() 接收数据
字符串前面添加b就可以转化成字节,如:b‘hhhsdf’
变量.encode("utf-8") 转化任意编码成字节,如:abc.encode("utf-8")
Windows默认使用gbk编码发送消息
socket模拟服务器处理响应
所有的linux里面的东西都对应一个文件
fd文件描述符,就是一个数字,对应一个特殊的文件,例如网络接口
- 主进程中等待socket,启用进程处理链接的同时应当继续调用
socket.close();多线程/协程都不需要在主线程中调用socket.close() -
socket.setblocking(False)设置套接字为非堵塞的方式
#非阻塞链接
tcp_server = socket(···)
tcp_server.setblocking(False) # 设置套接字为非堵塞的方式
client_socket_list = list()
while True:
try:
new_socket, new_address = tcp_server.accept()
except Exception as ret:
print(“——-没有新的客户的客户端到来——”)
else:
print(“—-只要没有异常,那么就意味着 来了一个新的客户大u呢——-”)
new_socket.setblocking(False)
client_socket_list.append(new_socket)
for client_socket in client_socket_list:
try:
recv_data = client_socet.recv(1024)
except Exception as ret:
print(“——这个客户端没有发送过来数据——”)
else:
if recv_data:
print(“——客户端发送过来了数据——”)
else:
client_socket.close()
client_socket_list.remove(client_socket)
- 处理客户端请求数据的响应中增加
Content-Length:body内容长度来告诉浏览器资源响应完毕,实现长链接
常用Linux命令
ps -aux查看所有进程
kill 进程ID可以杀死指定进程
sudo dhclient 管理员桥接网络设置,将虚拟机IP网段与本机保持一致
mkdir 文件夹 创建目录
touch 文件名 创建指定文件名的文件
ls 查看当前目录下的文件或文件夹
ls -a 包含隐藏文件.开头的文件就是隐藏的
cp 当前文件 目标文件 拷贝当前文件到目标文件(自动创建目标文件)
mv修改目标文件名称
cat查看指定文件内容
tail -f持续查看文件内容
常用方法
- 在方法中修改全部变量时,如果使用赋值= ,需要在方法中提前声明
global变量 -
print("\r拷贝进度:%.2f" % (2*100/123),end="")实现单行输出 -
help(对象名)获取对象帮助信息 -
range(10)自动生成10以内列表
from collections import Iterator/Iterable迭代器
from collections import Iterable
isinstance(验证对象,Iterable)返回True表示可以迭代
特性/伪协程
- 节省内存空间,因为不会立刻计算
-
[x*2 for x in range(10)]只是列表(x*2 for x in range(10))这样返回的就是一个可迭代对象 - 包含
yield方法就会变成迭代,执行一部分就直接返回数据 - 可以暂停代码,在yield语句位置
-
form greenlet import greenlet封装来yield的实现greenlet(普通方法名)方法中不再需要出现yield实现协程效果
- 一个普通对象如果要实现迭代功能需要实现:
def __iter__(self):返回自身;def __next__(self):返回每次要取的值 -
raise StopIteration结束迭代 -
next(对象)获得下一个值 -
.send(参数)可迭代中修改对象的返回值,需要在next后使用,否则参数只能是None
import multiprocessing进程
-
.Process创建进程对象 -
.Queue创建队列,.put()添加数据,.get()获取一条数据没有会等待,.get_nowait()不等待取数据,.full()队列是否满了,.empty()队列是否空了 -
.Pool(3)定义一个进程池,.apply_async( 方法名,参数)空闲子进程调用方法,.join()等待close后 结束进程池 -
.Manager().Queue()可传递到进程池
import threading线程
-
threading.Thread(target=方法名,args=参数)将指定方法添加到多任务中,参数是元组 -
.start()开始执行多任务 -
.enumerate()获得已有线程列表 -
.Lock()创建线程锁,返回锁对象.acquire()上锁,.release()解锁
import gevent协程
只有遇到延时操作会自动切换协程,否则只会顺序执行
geven是对 greenlet的封装,greenlet是对yield的封装
-
gevent.spawn(方法,方法参数)创建一个协程对象 -
gevent.getcurrent()获得当前运行的协程对象 -
gevent.sleep(1)休息一秒 -
.join()等待协程运行gevent.joinall([gevent对象])多个等待 -
gevent.monkey.patch_all()程序中用到time语法的耗时操作,转换成gevent中自己实现的模块
import os 文件操作
-
.mkdir创建文件夹 -
.listdir获得文件夹下的所有文件列表 -
with open('','wb')保证文件会自动关闭
import urllib网络请求
-
urllib.request.urlopen(‘网址’).read()获得响应数据流
import re正则
通用正则
| 字符 | 功能 |
|---|---|
| . | 匹配任意1个字符(除了\n) |
| [] | 匹配[]中列举的字符 |
| \d | 匹配数字0-9 |
| \D | 匹配非数字 |
| \s | 匹配空白 空格 tab键 |
| \S | 匹配非空白 |
| \w | 匹配单词字符a-z A-Z 0-9 _ 汉字 |
| \W | 匹配非单词字符 |
| —- | 多次匹配⬇️ |
| * | 匹配前一个字符出现0或无限次 |
| + | 匹配前一个字符出现1或无限次 |
| ? | 匹配前一个字符出现1或0次 |
| {m} | 匹配前一个字符出现m次 |
| {m,n} | 匹配前一个字符出现从m到n次 |
| —— | 开始结束⬇️ |
| ^ | 匹配字符串开始 |
| $ | 匹配字符串结尾 |
| — | 匹配分组⬇️ |
| 匹配左右任意一个字符 | |
| (abc) | 将括号中字符作为一个分组 |
| \num | 引用分组num匹配到的字符串 |
| (?p<name>) | 分组起别名 |
| (?p=nam) | 引用别名为name分组匹配到的字符串 |
-
[a-zA-Z0-9_]{4,20}@163\.com$一个邮箱正则,大小写字母数字下划线 长度4-20 @163.com结尾 -
<(\w*)>.*</\1>\num的用法\1代表前面分组中的值如<h1></h1>
re模块高级用法
-
re.match(r”正则”,用户输入多字符串或列表)获得所有匹配对象 -
re.search(r”正则”,字符串或列表)匹配到就结束 -
.group()返回所有匹配值 -
re.findall()搜索所有匹配 列表 -
re.sub(r正则,替换值,用户输入字符串)将匹配到的数据进行替换,返回替换后的值;替换值可以是一个函数 -
re.split(r”:| ”,用户输入的字符串)使用冒号或空格切割并返回一个列表
import random随机
.choice(列表)随机获取一个值