[关闭]
@WillireamAngel 2018-06-25T06:43:18.000000Z 字数 5102 阅读 1164

WebSocket

Python


socket

定义

socket,套接字,是应用在应用层和传输层之间的抽象层,将TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中的通信。

socket的基本表示形式:IP+协议+端口。

通信

socket是一种"打开—读/写—关闭"模式的实现,服务器和客户端各自维护一个"文件",在建立连接打开后,可以读取对方内容或者向自己文件写入内容供对方读取,通讯结束时关闭文件。

通信流程

  1. 服务器根据地址类型(ipv4,ipv6)、socket类型、协议创建socket
    服务器为socket绑定ip地址和端口号;
  2. 服务器socket监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有被打开;
  3. 客户端创建socket;
  4. 客户端打开socket,根据服务器ip地址和端口号试图连接服务器socket;
  5. 服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,直到客户端返回连接信息。这时候socket进入阻塞状态,所谓阻塞即accept()方法一直到客户端返回连接信息后才返回,开始接收下一个客户端请求;
  6. 客户端连接成功,向服务器发送连接状态信息;
  7. 服务器accept()方法返回,连接成功;
  8. 客户端向socket写入信息;
  9. 服务器读取信息;
  10. 客户端关闭;
  11. 服务器端关闭。

实现

python socket模块支持建立和处理socket连接。
参照:https://docs.python.org/3/library/socket.html
server_socket:

  1. import socket
  2. server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  3. hostname = socket.gethostname()
  4. port = 1234
  5. server_socket.bind((hostname,port))
  6. server_socket.listen(5)
  7. while True:
  8. client_socket, addr = server_socket.accept()
  9. print('connect_address:%s' %str(addr))
  10. msg='welcome to socket test!'+'\r\n'
  11. client_socket.send(msg.encode('utf-8'))
  12. client_socket.close()

client_socket:

  1. import socket
  2. client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
  3. hostname = socket.gethostname()
  4. port = 1234
  5. client_socket.connect((hostname,port))
  6. msg = client_socket.recv(1024)
  7. client_socket.close()
  8. print(msg.decode('utf-8'))

执行python3 server_sockpython3 client_sock
分别得到如下信息:

  1. connect_address:('192.168.152.1', 5892)
  1. welcome to socket test!

参照:https://docs.python.org/3/library/socket.html

WebSocket

了解了socket的大概知识,就谈谈Websocket。

定义

WebSocket是一种在单个TCP连接上进行全双工通讯的协议,在HTML5中定义了WebSocket协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

基于单TCP连接的双向通信和基于多TCP连接的单向通信相比,很显著地节约了用于创建TCP连接的服务器资源和带宽,极大地提高了通信效率,通讯更加实时。

优点

  • 较少的控制开销。创建连接后,服务器和客户端之间交换数据时的数据包头部产生的开销明显减少了。
  • 更强的实习性。协议是全双工的,服务器可以主动给客户端下发资源,相对于单向监听等待和长轮询,延迟明显较少,短时间内能传递更多的数据。
  • 保持连接状态。HTTP本身无状态,状态认证实现需要Cookie和Session等,而WebSocket本身是建立在连接基础上的,使得其成为一种有状态的协议。
  • 更好的二进制支持。WebScoket定义了二进制帧,可以更轻松地处理二进制内容。
  • 可以支持扩展。WebSocket定义了扩展,用户可以扩展协议。
  • 更好的压缩效果。WebSocket在适当的扩展支持下,可以沿用之前的上下文,在传递类似数据时,可提高压缩率。

服务器支持

目前支持WebSocket的服务器有很多,主要包括php,ruby,TomCat、node.js、nginx、python、Django等。
安装websockets模块:

  1. pip install websockets

本文以python实现WebSocket示例:
websocket_server:

  1. import asyncio
  2. import websockets
  3. async def hello(websocket,path):
  4. name = await websocket.recv()
  5. print(f"< {name}")
  6. greeting = f"hello {name}!"
  7. await websocket.send(greeting)
  8. print(f"> {greeting}")
  9. start_server = websockets.serve(hello, 'localhost', 8765)
  10. asyncio.get_event_loop().run_until_complete(start_server)
  11. asyncio.get_event_loop().run_forever()

websocket_client:

  1. import asyncio
  2. import websockets
  3. async def hello():
  4. async with websockets.connect(
  5. 'ws://localhost:8765') as websocket:
  6. name = input("What's your name? ")
  7. await websocket.send(name)
  8. print(f"> {name}")
  9. greeting = await websocket.recv()
  10. print(f"< {greeting}")
  11. asyncio.get_event_loop().run_until_complete(hello())

上例涉及到asyncio异步I/O,相关的操作可以参考:
https://docs.python.org/3/library/asyncio.html

HTTP2.0

谈及websocket的服务端通信和二进制支持,我们很容易想到HTTP2.0的新特性。

简介

HTTP/2.0,超文本传输协议 v2.0,是下一代HTTP协议,由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发,将全面用于HTTPS,实际上是在性能提升的同时增加了安全性。

特性

(相对于HTTP1.1)
作为HTTP1.1的大版本跨越,HTTP 2.0把解决性能问题的方案内置在了传输层,添加二进制帧分层,通过多路复用来减少延迟,通过压缩 HTTP首部降低开销,同时增加请求优先级和服务器端推送的功能。

WebSocket vs HTTP2.0

WebSocket和HTTP/2.0有一个类似的特性,支持服务端推送(HTTP2.0)或者双向通信(WebSocket),但实际上从设计目标和支持上都大有不同。

参考链接

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注