pythonsocket多线程,socket 多线程
python中建立多线程的问题
这个不用你去写。在python里现成的。只要重载ThreadingServer和SocketServer就可以了。你自己去看python帮助里的例子代码,也可以去site-packages里去看源码。
大概的是这样
soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
soc.bind(....)
while True:
client=soc.listen(1)
start_thread(function_thread, (client,))
def function_thread(client):
buf=client.recv()
....
python socket如何实现一个服务器对多个客户端进行交互。
使用多线程,下面的代码,简单实现一个多线程的web服务器:
#coding=utf-8
import?socket
import?threading
from?time?import?sleep
def?response(sock,?addr):
????print?"收到请求"
????data?=?sock.recv(1024)
????print?data
????sock.send(html)
????sock.close()
html?=?'''HTTP/1.1?200?OK\nContent-Type:?text/html\n\r\nHello?world!'''
s?=?socket.socket(socket.AF_INET,?socket.SOCK_STREAM)
s.bind(('0.0.0.0',?80))
s.listen(50)
print?"正在等待连接……"
while?1:
????sleep(0.1)
????sock,addr?=?s.accept()
????t?=?threading.Thread(target=response,?args=(sock,addr))
????t.start()

同步socket, 异步socket, 多线程socket, 多进程socket
socket常用,本文立足同步和异步socket,以及现有的socketserver库。
同步socket一般有利用socket库直接,就可以写出tcp或udp的套接字
socketserver提供的线程或进程方式的socket
利用python 3.5+的asyncio协议,封装一个协程的socket server ,普通的socket客户也可以连接。
服务器端
客户端
为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从缓存中取出定长的报头,然后再取真实数据
构造报头信息
服务端
客户端
粘包,分包都tcp
tcp为什么会有粘包分包这些情况:
1.服务端处理不过来
2.客户端采用优化纳格尔算法,达到一定字节才发
怎么处理:
1. 客,服双方确定包头规范,根据包头的信息取包长度
2. 客户端发送带上标记位,如\n, 服务端根据标记取包
服务器端
客户端
服务器端
客户端
服务器端
客户端
封装了socket,而且解决了Io阻塞问题
服务端
客户端
客户端
参考:
多线程 python和多进程的区别
前面的章节,我们刚刚介绍过socket和socketserver网络编程。
在socketserver服务端代码中有这么一句:
server = socketserver.ThreadingTCPServer((ip,port), MyServer)
ThreadingTCPServer这个类是一个支持多线程和TCP协议的socketserver,它的继承关系是这样的:
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
右边的TCPServer实际上是主要的功能父类,而左边的ThreadingMixIn则是实现了多线程的类,?ThreadingTCPServer自己本身则没有任何代码。
MixIn在Python的类命名中很常见,称作“混入”,戏称“乱入”,通常为了某种重要功能被子类继承。
我们看看一下ThreadingMixIn的源代码:
class ThreadingMixIn:
daemon_threads = False
def process_request_thread(self, request, client_address):
try:
self.finish_request(request, client_address)
self.shutdown_request(request)
except:
self.handle_error(request, client_address)
self.shutdown_request(request)
def process_request(self, request, client_address):
t = threading.Thread(target = self.process_request_thread,
args = (request, client_address))
t.daemon = self.daemon_threads
t.start()
在ThreadingMixIn类中,其实就定义了一个属性,两个方法。其中的process_request()方法实际调用的正是Python内置的多线程模块threading。这个模块是Python中所有多线程的基础,socketserver本质上也是利用了这个模块。
socketserver通过threading模块,实现了多线程任务处理能力,可以同时为多个客户提供服务。
那么,什么是线程,什么是进程?
进程是程序(软件,应用)的一个执行实例,每个运行中的程序,可以同时创建多个进程,但至少要有一个。每个进程都提供执行程序所需的所有资源,都有一个虚拟的地址空间、可执行的代码、操作系统的接口、安全的上下文(记录启动该进程的用户和权限等等)、唯一的进程ID、环境变量、优先级类、最小和最大的工作空间(内存空间)。进程可以包含线程,并且每个进程必须有至少一个线程。每个进程启动时都会最先产生一个线程,即主线程,然后主线程会再创建其他的子线程。
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不独立拥有系统资源,但它可与同属一个进程的其它线程共享该进程所拥有的全部资源。每一个应用程序都至少有一个进程和一个线程。在单个程序中同时运行多个线程完成不同的被划分成一块一块的工作,称为多线程。
举个例子,某公司要生产一种产品,于是在生产基地建设了很多厂房,每个厂房内又有多条流水生产线。所有厂房配合将整个产品生产出来,单个厂房内的流水线负责生产所属厂房的产品部件,每个厂房都拥有自己的材料库,厂房内的生产线共享这些材料。公司要实现生产必须拥有至少一个厂房一条生产线。换成计算机的概念,那么这家公司就是应用程序,厂房就是应用程序的进程,生产线就是某个进程的一个线程。
线程的特点:
线程是一个execution context(执行上下文),即一个cpu执行时所需要的一串指令。假设你正在读一本书,没有读完,你想休息一下,但是你想在回来时继续先前的进度。有一个方法就是记下页数、行数与字数这三个数值,这些数值就是execution context。如果你的室友在你休息的时候,使用相同的方法读这本书。你和她只需要这三个数字记下来就可以在交替的时间共同阅读这本书了。
线程的工作方式与此类似。CPU会给你一个在同一时间能够做多个运算的幻觉,实际上它在每个运算上只花了极少的时间,本质上CPU同一时刻只能干一件事,所谓的多线程和并发处理只是假象。CPU能这样做是因为它有每个任务的execution context,就像你能够和你朋友共享同一本书一样。
进程与线程区别:
同一个进程中的线程共享同一内存空间,但进程之间的内存空间是独立的。
同一个进程中的所有线程的数据是共享的,但进程之间的数据是独立的。
对主线程的修改可能会影响其他线程的行为,但是父进程的修改(除了删除以外)不会影响其他子进程。
线程是一个上下文的执行指令,而进程则是与运算相关的一簇资源。
同一个进程的线程之间可以直接通信,但是进程之间的交流需要借助中间代理来实现。
创建新的线程很容易,但是创建新的进程需要对父进程做一次复制。
一个线程可以操作同一进程的其他线程,但是进程只能操作其子进程。
线程启动速度快,进程启动速度慢(但是两者运行速度没有可比性)。
由于现代cpu已经进入多核时代,并且主频也相对以往大幅提升,多线程和多进程编程已经成为主流。Python全面支持多线程和多进程编程,同时还支持协程。