python socket服务端,python websocket client
仅供参考,转载请注明出处。
描述需求。当开发web服务器接受http请求时,当recv等待接受数据时,套接字被阻塞。
用于等待http发送的数据。
那么这种等待实际上占用了服务器的资源。
为了节省这种资源,可以采用非阻塞的方式进行套接字等待监控,即每次轮询监控都不会阻塞等待。
更改为非阻塞模式。
首先,将套接字更改为非阻塞模式,并创建一个专门存储client_socket的列表。
#设置非阻塞模式
server _ socket . set blocking(False)
#创建一个包含子进程的列表。
Client_socket_list=list() #因为是非阻塞的,所以需要存储接收到的Client_socket进行处理。
tcp的主套接字被设置为等待http请求的到达。因为没有jam,循环肯定会报错,所以需要处理异常抛出。
操作效果如下:
然后循环client_socket的列表。
按如下方式运行:
那么这意味着什么呢?
这是因为在非阻塞的过程中,client_socket执行后会被关闭,但是由于它是预先存储在列表组中,然后再次循环,所以会重复执行同一个client_socket,导致client_socket关闭错误(因为已经是第一次关闭了,当然重复recv时会报错)。
那就处理好这次停工吧。
还有一个问题,就是什么时候可以关闭client_socket?
想想吧。client_socket在阻塞recv的时候,只要数据来了,就不会抛出异常。只要不抛出异常,肯定是时候关闭client_socket,从列表中删除,避免重复循环。
处理对client_socket的循环调用
操作效果如下:
那么这里就完成了非阻塞web服务。但是有一个性能不好的问题,下次再讨论。
你可以提前考虑。如果存储client_socket的列表越来越大,然后需要很长时间轮询,就会导致访问一个页面很慢。我们应该如何处理这个问题?
完整的代码如下#coding=utf-8。
从套接字导入*
进口re
导入线程
导入时间
定义句柄_客户端(客户端_套接字):
“为客户服务”
#接收对方发送的数据
recv _ data=client _ socket . recv(1024)。Decode (UTF-8) # 1024表示这次接收的最大字节数
#打印从客户端发送的数据内容
#print(客户端接收:,接收数据)
request _ header _ lines=recv _ data . split lines()
对于请求标题行中的行:
打印(行)
#返回浏览器数据
#设置内容正文
#使用常规匹配来匹配文件路径。
打印(-,request_header_lines[0])
打印(文件路径-,。/html/ re.match(r[^/]/([^\s]*),request_header_lines[0]).组(1))
/([^\s]*),request_header_lines[0 re.match(r[^/])
如果ret:
文件路径=。/html/ ret.group(1)
if file_path==。/html/:
文件路径=。/html/index.html
打印(文件路径*******,文件路径)
尝试:
#设置返回的头信息头
response _ headers= http/1.1 200 ok \ r \ n # 200表示已经找到该资源。
Response_headers=\r\n #正文中有一个空行
#读取html文件内容
File_name=file_path #设置读取文件的路径
F=open(文件名, rb) #以二进制读取文件的内容
response_body=f.read()
f.close()
#向浏览器返回数据
client _ socket . send(response _ headers . encode( utf-8 )#对utf-8进行代码转换,并将数据发送到浏览器。
client _ socket . send(response _ body)#转码utf-8并将数据发送到浏览器
除了:
#如果文件未找到,则打印404未找到
#设置返回的头信息头
Response _ headers= http/1.1 404未找到\ r \ n # 200表示已找到该资源
Response_headers=\r\n #正文中有一个空行
response_body= h1对不起,找不到文件/h1
response=response_headers响应_正文
client _ socket . send(response . encode( utf-8 ))
# client _套接字. close()
def main():
#创建套接字
服务器套接字=套接字(AF_INET,SOCK_STREAM)
#先设置服务器关闭后立即释放资源,即服务器波动4次,保证下次运行程序时能立即绑定7788端口。
server _ SOCKET . setsockopt(SOL _ SOCKET,SO_REUSEADDR,1)
#设置服务器提供的服务的端口号。
server_socket.bind(( ,7788))
#使用socket创建的socket的默认属性是active,使用listen监听连接将其更改为passive。
Server_socket.listen(128) #最多可以监听128个连接
#设置非阻塞模式
server _ socket . set blocking(False)
#创建一个包含子进程的列表。
Client_socket_list=list() #因为是非阻塞的,所以需要存储接收到的Client_socket进行处理。
#打开while循环以处理访问请求。
虽然正确:
#时间.睡眠(0.5)
#如果有一个新的客户端链接到服务器,那么将创建一个新的套接字来服务这个客户端。
# client_socket用于服务此客户端。
# server_socket可以被保存以等待其他新的客户端连接,而True:
尝试:
client_socket,client addr=server _ socket . accept()
例外情况为e:
Print ( - 1还没有http请求到达,e) #因为是非阻塞的,所以可能会有套接字异常。
否则:
Print (-2有http请求来了!- )
Client _ socket . Set blocking(false)#将client _ socket设置为非阻塞模式。
client _ socket _ list . append(client _ socket)#向列表中添加子进程
#遍历客户端套接字列表
对于客户端套接字列表中的客户端套接字:
尝试:
句柄_客户端(客户端_套接字)
例外情况为e:
Print (-3client _ socket未收到http请求,e)
否则:
Print (-4client _ socket接收http请求并处理数据)
client _套接字. close()
客户端套接字列表删除(客户端套接字)
if __name__==__main__ :
主()
关注微信微信官方账号,回复【数据】,Python,PHP,JAVA,web,即可获取Python,PHP,JAVA,前端等视频数据。
来自海洋的渔夫原创作品,
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。