在本文中,我们将为您详细介绍在python中使用SocketServer框架创建多线程服务器的相关知识,并且为您解答关于pythonsocket服务器多线程的疑问,此外,我们还会提供一些关于pytho
在本文中,我们将为您详细介绍在python中使用SocketServer框架创建多线程服务器的相关知识,并且为您解答关于python socket服务器多线程的疑问,此外,我们还会提供一些关于python Socket socketserver、python SocketServer 源码分析、python SocketServer 简单服务器例子、Python SocketServer 网络服务器的框架一:基本知识的有用信息。
本文目录一览:- 在python中使用SocketServer框架创建多线程服务器(python socket服务器多线程)
- python Socket socketserver
- python SocketServer 源码分析
- python SocketServer 简单服务器例子
- Python SocketServer 网络服务器的框架一:基本知识
在python中使用SocketServer框架创建多线程服务器(python socket服务器多线程)
#!/usr/bin/env python#-*- coding: utf-8 -*-import syssys.dont_write_bytecode = Trueimport shleximport subprocessimport SocketServersess = []class TCPHandler(SocketServer.BaseRequestHandler): def handle(self): global sess sess.append(self.request) ip,port = self.client_address print "#%d: client %s:%d"%(len(sess),ip,port) while True: cmd = self.request.recv(8192) out = subprocess.check_output(shlex.split(cmd),stderr=subprocess.STDOUT,shell=True) self.request.send(out) self.request.close()class ThreadedTCPServer(SocketServer.ThreadingMixIn,SocketServer.TCPServer): passif __name__ == "__main__": port = 4242 svr = ThreadedTCPServer(("",port),TCPHandler) print ":%d"%port svr.serve_forever()
答案1
小编典典它比您想象的简单得多:
class ThreadedTCPServer(SocketServer.ThreadingMixIn,SocketServer.TCPServer): pass
比起您,您只需要使用新ThreadedTCPServer
的即可TCPServer
。
有关更多信息,您可以阅读一些文档。
但是,在您的代码中您犯了一些错误:
- 该
target
参数必须是一个callable
对象不是“已调用”对象。 - 要处理许多请求,您需要构建一个线程池。如果仅使用一个线程,则它是主线程还是“子”线程没有任何区别。
python Socket socketserver
Socket
套接字
socket的 类型 实现socket对象时传入 到socket 类中
socket.AF_INET 服务器间的通讯 IPv4
socket.AF_INET6 IPv6
socket.SOCK_STREAM 流试 tcp 传输方式 默认类型
socket.SOCK_DGRAM 包式 udp 传输方式
返回前端数据 需要先发送报头
b''HTTP/1/1 200 OK \r\n\r\n''
基于 Tcp 传输方式
服务端 server
import socket
server = socket.socket()
# 允许地址重用
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
# 绑定 ip 及 端口
server.bind(("192.168.15.100", 8001))
监听 tcp 传入链接 可设置链接个数 listen(4)
server.listen()
# 等待建立链接 conn 管道 addr 客户端的地址
conn, addr = server.accept()
#接收数据
content = conn.recv(1024).decode("utf-8")
print(content)
# 发送数据
conn.send("再见".encode("utf-8"))
# 循环发送数据 直到数据发送完毕
conn.sendall("再见..........".encode("utf-8"))
# 关闭
conn.close()
server.close()
客户端 client
import socket
clinet = socket.socket()
clinet.connect(("192.168.15.100", 8001))
clinet.send(st.encode("utf-8"))
clinet.recv(1024).decode("utf-8")
clinet.close()
基于 Udp 传输方式
服务端
import socket
server = socket.socket(type=socket.SOCK_DGRAM)
server.bind(("127.0.0.1", 8001))
# 等待接收数据
conn, addr = server.recvfrom(1024)
st = conn.decode("utf-8")
# 向某个地址 返回数据
server.sendto(st.encode("utf-8"), addr)
客户端
import socket
clinet = socket.socket(type=socket.SOCK_DGRAM)
clinet.sendto(''你好啊!'', ("127.0.0.1", 8001))
conn, addr = clinet.recvfrom(1024)
print(conn.decode("utf-8"))
server.sendto(st.encode("utf-8"), addr)
缓冲区
作用:
防止数据丢失
输入缓冲区 #recv 输出缓冲区 #send
粘包
粘包(tcp的两种粘包现象)
-
连续发送小的数据,并且每次发送之间的时间间隔很短(输出缓冲区:两个消息在缓冲区黏在一起了)
原因是TCP为了传输效率,做了一个优化算法(Nagle),减少连续的小包发送(因为每个消息被包裹以后,都会有两个过程:1 组包 2拆包)
-
第一次服务端发送的数据比我客户端设置的一次接收消息的大小要大,那么接收不完,第二次再接收的时候,就会将第一次剩余的消息接收到
粘包的根本原因是因为:双方不知道对方发送消息的大小
-
解决方案一:
发送消息之前,先计算要发送消息的长度,然后先将消息长度发送过去,对方给你回一个确认收到长度的信息,然后根据接收到的消息长度来修改自己一次接收消息的大小 这个过程多了一次交互
-
粘包解决方案二
使用 **struct ** 模块打包
tcp和udp的区别
tcp协议:面向连接,消息可靠,相对udp来讲,传输速度慢,消息是面向流的,无消息保护边界0 udp协议:面向无连接,消息不可靠,传输速度快,消息是面向包的,有消息保护边界.
socketserver
- 简化网络服务端的编写
服务端 SocketServer模块与简单并发服务器
import socketserver
import struct
class Myserver(socketserver.BaseRequestHandler):
# 定义一个方法 handle 方法名字不可以变
def handle(self):
try:
while 1: # 循环接受 回复 数据
# self.request 就是 conn 链接通道
client_data = self.request.recv(1024).decode("utf-8")
print(client_data)
# 返回信息
self.request.send("输入>>>".encode("utf-8"))
except ConnectionResetError as c:
print(c)
if __name__ == "__main__":
server_ip = (''127.0.0.1'',8001)
# 地址重用
# socketserver.TCPServer.allow_reuse_address = True
# 绑定ip 端口 启动 Myserver 类 ThreadingTCPServer>>>多线程的TCP服务端
server = socketserver.ThreadingTCPServer(server_ip, Myserver)
# 永久执行下去
server.serve_forever()
FTP
#进度条打印,print版
import time
for i in range(20):
#\r 回到行首打印内容,如果同一行有内容,那么就被抹掉了
n = ''>'' * i
print(''\r%s'' %n,end='''')
time.sleep(0.5)
#进度条打印,sys版
import sys
import time
for i in range(10):
sys.stdout.write(''>'')
sys.stdout.flush()
time.sleep(0.5)
#搞百分比的样子
#0.42857142857142855 改成两位数,不进行四舍五入
print(3/7) #0.42857142857142855
print(round(3/7,2)) #0.43 43%
print(int(3/7*100))
python SocketServer 源码分析
附上原文链接: http://beginman.cn/python/2015/04/06/python-SocketServer/
python SocketServer 简单服务器例子
最近在看python的socket,SocketServer。试着写了一个简单的例子,允许多个客服端或浏览器同时访问。这里只写了服务器,木写客户端,你可以用浏览器访问。不对的地方和需要完善的地方,请指出,大家一块进步。
#server
from SocketServer import TCPServer, ThreadingMixIn, StreamRequestHandler
#创建多线程 允许多个客户端同时访问
class server(TCPServer,ThreadingMixIn):
pass
#该函数 对接收的数据进行处理加工
def changData(x):
z=x.upper()
return z
#继承StreamRequestHandler类 ,改写handle 函数
class dataHandle(StreamRequestHandler):
def handle(self):
cliend_ip=self.request.getpeername() #得到访问服务器的ip 返回的是一个元组 ,包含 ip ,port
print "client_ip:",cliend_ip
data=self.request.recv(2048)#接收数据
print "receive data:",data
r=''jkljll''
self.wfile.write(changData(data))#向客服端发送数据
self.wfile.write(''\n'')
self.wfile.write(data)#向客服端发送数据
servers=server((''192.168.0.108'',1278),dataHandle)#server()需要两个参数,一个是(ip,port),另一个是继承StreamRequestHandler后的类
servers.serve_forever() # 服务器无限循环运行
Python SocketServer 网络服务器的框架一:基本知识
原文来自http://docs.python.org/library/socketserver.html
一、简介
Python的SocketServer模块简化了编写网络服务器,他有四个基本的服务器类:「1、TCPServer2、UDPServer 3、UnixStreamServer 4、UnixDatagramServer」
1、TCPServer使用的互联网TCP协议,它提供连续的客户端和服务器之间的数据流。
2、UDPServer使用离散的数据包的信息,可以不按顺序到达
3、UnixStreamServer和UnixDatagramServer 是不常使用的,这两个类是很相似的
二、基本知识
通常这四个类在处理请求时必须完成整个过程后才能处理下一个请求。(如果每个请求的处理过程需要很长的时间才能完成或者它传回大量数据到客户端时非常缓慢时,另一个请求只能等待)。要解决这个问题可以创建一个单独的进程或线程来处理每个请求。 ForkingMixIn和ThreadingMixIn混合类可用于支持异步操作。
创建一个服务器需要几个步骤:
1、首先你要创建一个请求处理程序的类,调用SocketServer类中的BaseRequestHandler子类,并重写它的handle()方法,这个方法会处理传入的请求
2、你必须实例化一个服务器类,它通过服务器地址和请求来处理程序类。
3、用handle_request() or serve_forever()方法来处理一个或多个请求。
三、继续
为防止线程在运行中突然挂掉了,所以在
继承ThreadingMixIn过程时
必须将
ThreadingMixIn类的属性
定义为
守护线程,这样服务器就知道是否应该等特
线程
或终止服务器,所以要明确设置。如果你想线程都是执行完自主关闭的(默认是False)。这就意味着Python 不会退出,直到所有的线程
ThreadingMixIn都结束。
四、注意
在Python3中,本模块为socketserver模块。在Python 2.x中,本模块为SocketServer模块。所以在用import导入时,要分情况导入,否则会报错。导入的代码如下:
try:
import socketserver #Python 3
except ImportError:
import SocketServer #Python 2
五、
+ ------------ +
BaseServer |
+ ------------ +
|
v
+ ----------- + + ------------------ +
| TCPSERVER | ------- | UnixStreamServer |
+ ----------- + + ------------------ +
|
v
+ ----------- + + -------------------- +
| UDPServer | -------> | UnixDatagramServer |
+ ----------- + + -------------------- +
class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
The mix-in class must come first, since it overrides a method defined in UDPServer. Setting the various attributes also change the behavior of the underlying server mechanism.
To implement a service, you must derive a class from BaseRequestHandler and redefine its handle() method. You can then run various versions of the service by combining one of the server classes with your request handler class. The request handler class must be different for datagram or stream services. This can be hidden by using the handler subclasses StreamRequestHandler or DatagramRequestHandler.
Of course, you still have to use your head! For instance, it makes no sense to use a forking server if the service contains state in memory that can be modified by different requests, since the modifications in the child process would never reach the initial state kept in the parent process and passed to each child. In this case, you can use a threading server, but you will probably have to use locks to protect the integrity of the shared data.
On the other hand, if you are building an HTTP server where all data is stored externally (for instance, in the file system), a synchronous class will essentially render the service “deaf” while one request is being handled – which may be for a very long time if a client is slow to receive all the data it has requested. Here a threading or forking server is appropriate.
In some cases, it may be appropriate to process part of a request synchronously, but to finish processing in a forked child depending on the request data. This can be implemented by using a synchronous server and doing an explicit fork in the request handler class handle() method.
Another approach to handling multiple simultaneous requests in an environment that supports neither threads nor fork() (or where these are too expensive or inappropriate for the service) is to maintain an explicit table of partially finished requests and to use select() to decide which request to work on next (or whether to handle a new incoming request). This is particularly important for stream services where each client can potentially be connected for a long time (if threads or subprocesses cannot be used). See asyncore for another way to manage this.
今天关于在python中使用SocketServer框架创建多线程服务器和python socket服务器多线程的介绍到此结束,谢谢您的阅读,有关python Socket socketserver、python SocketServer 源码分析、python SocketServer 简单服务器例子、Python SocketServer 网络服务器的框架一:基本知识等更多相关知识的信息可以在本站进行查询。
本文标签: