一个程序员自学中

使用python搭建Socket服务器

2020-06-27  本文已影响0人  小船翻不翻

#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次握手操作

  1. 客户端发起链接syn
  2. 服务器回应ack并发起syn
  3. 客户端回应ack

4次挥手操作,一般由客户端发起关闭

  1. 客户端发起关闭‘发送’
  2. 服务器回应接收到
  3. 服务器发起关闭‘接收’
  4. 客户端回应接收到,并等待一段时间(2-5min)释放资源,又叫2msl两倍等待释放

.listen(128) 被动模式 128代表同一时间可以处理的链接数量
.accept() 接收数据

字符串前面添加b就可以转化成字节,如:b‘hhhsdf’
变量.encode("utf-8") 转化任意编码成字节,如:abc.encode("utf-8")
Windows默认使用gbk编码发送消息

socket模拟服务器处理响应

所有的linux里面的东西都对应一个文件
fd文件描述符,就是一个数字,对应一个特殊的文件,例如网络接口

#非阻塞链接
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)

常用Linux命令

ps -aux查看所有进程
kill 进程ID可以杀死指定进程
sudo dhclient 管理员桥接网络设置,将虚拟机IP网段与本机保持一致
mkdir 文件夹 创建目录
touch 文件名 创建指定文件名的文件
ls 查看当前目录下的文件或文件夹
ls -a 包含隐藏文件.开头的文件就是隐藏的
cp 当前文件 目标文件 拷贝当前文件到目标文件(自动创建目标文件)
mv修改目标文件名称
cat查看指定文件内容
tail -f持续查看文件内容

常用方法

  1. 在方法中修改全部变量时,如果使用赋值= ,需要在方法中提前声明 global变量
  2. print("\r拷贝进度:%.2f" % (2*100/123),end="")实现单行输出
  3. help(对象名)获取对象帮助信息
  4. range(10)自动生成10以内列表

from collections import Iterator/Iterable迭代器

from collections import Iterable
isinstance(验证对象,Iterable)返回True表示可以迭代

特性/伪协程

  1. 一个普通对象如果要实现迭代功能需要实现:def __iter__(self):返回自身;def __next__(self):返回每次要取的值
  2. raise StopIteration结束迭代
  3. next(对象)获得下一个值
  4. .send(参数)可迭代中修改对象的返回值,需要在next后使用,否则参数只能是None

import multiprocessing进程

  1. .Process 创建进程对象
  2. .Queue创建队列,.put()添加数据,.get()获取一条数据没有会等待,.get_nowait()不等待取数据,.full()队列是否满了,.empty()队列是否空了
  3. .Pool(3)定义一个进程池,.apply_async( 方法名,参数)空闲子进程调用方法,.join()等待close后 结束进程池
  4. .Manager().Queue()可传递到进程池

import threading线程

  1. threading.Thread(target=方法名,args=参数)将指定方法添加到多任务中,参数是元组
  2. .start()开始执行多任务
  3. .enumerate()获得已有线程列表
  4. .Lock()创建线程锁,返回锁对象 .acquire()上锁,.release()解锁

import gevent协程

只有遇到延时操作会自动切换协程,否则只会顺序执行
geven是对 greenlet的封装,greenlet是对yield的封装

  1. gevent.spawn(方法,方法参数)创建一个协程对象
  2. gevent.getcurrent()获得当前运行的协程对象
  3. gevent.sleep(1)休息一秒
  4. .join() 等待协程运行gevent.joinall([gevent对象])多个等待
  5. gevent.monkey.patch_all()程序中用到time语法的耗时操作,转换成gevent中自己实现的模块

import os 文件操作

  1. .mkdir创建文件夹
  2. .listdir获得文件夹下的所有文件列表
  3. with open('','wb') 保证文件会自动关闭

import urllib网络请求

  1. 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分组匹配到的字符串
  1. [a-zA-Z0-9_]{4,20}@163\.com$一个邮箱正则,大小写字母数字下划线 长度4-20 @163.com结尾
  2. <(\w*)>.*</\1>\num的用法\1代表前面分组中的值如<h1></h1>

re模块高级用法

  1. re.match(r”正则”,用户输入多字符串或列表)获得所有匹配对象
  2. re.search(r”正则”,字符串或列表)匹配到就结束
  3. .group()返回所有匹配值
  4. re.findall()搜索所有匹配 列表
  5. re.sub(r正则,替换值,用户输入字符串)将匹配到的数据进行替换,返回替换后的值;替换值可以是一个函数
  6. re.split(r”:| ”,用户输入的字符串)使用冒号或空格切割并返回一个列表

import random随机

.choice(列表)随机获取一个值

上一篇下一篇

猜你喜欢

热点阅读