python-socket、websocket协议相关知识

socket、websocket通信协议概念

socket通信

socket通信是基于TCP/IP协议,适用于传输大量数据和可靠的连接。它在网络编程中应用广泛,但不适用于实时性要求较高的场景。在Python中,socket和socketserver是两个用于网络编程的库。socket库提供了基本的网络通信功能,包括创建套接字、绑定地址、监听连接等。它主要用于实现客户端或服务器端的网络通信。使用socket库时,需要手动处理数据的发送和接收,以及错误处理等。socketserver库是基于socket库的一个扩展库,它提供了更高级的网络通信功能,如多线程、异步I/O等。它主要用于实现高性能的网络服务器。使用socketserver库时,可以更方便地处理多个客户端连接,以及并发请求等。

  • 如果只需要实现基本的客户端或服务器端网络通信,可以使用socket库。但如需要处理多个客户端连接或高性能的网络服务器,建议使用socketserver库。

websocket协议通信

WebSocket协议是一种基于TCP的网络通信协议,它允许在客户端和服务器之间进行全双工通信。WebSocket协议的握手过程需要进行HTTP握手。在Python中,websocket和websockets是两个用于实现WebSocket协议的库。它们提供了在客户端和服务器之间进行双向通信的功能。

  • websocket库是同步的,而websockets库是异步的。如果你需要处理大量的并发连接,那么websockets库可能会更适合,因为它不会阻塞主线程。
  • websockets库提供了更简洁的API,使得编写WebSocket服务器变得更加容易。但是,如果需要更多的控制和灵活性,那么websocket库可能会更适合。

代码案例

socket案例

server端

1. 通过socket模块创建server端

步骤:

1. 创建socket对象,s=socket.socket()

2. 绑定ip/端口地址,s.bind((ip,port)) #参数为元组

3. 监听端口,s.listen()

4. 开启循环,接受客户端连接(s.accept),并开启多线程处理信息。

import socket
import threading
import time
import sys


def socket_service():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(('127.0.0.1', 6668))
        s.listen(10)
    except socket.error as msg:
        print(msg)
        sys.exit(1)
    print('Waiting connection...')

    while True:
        conn, addr = s.accept()
        t = threading.Thread(target=deal_data, args=(conn, addr))
        t.start()


def deal_data(conn, addr):
    print('Accept new connection from {0}'.format(addr))
    conn.send(('Hi, Welcome to the server!').encode())
    while 1:
        data = conn.recv(1024)
        print('{0} client send data is {1}'.format(addr,
                                                   data.decode()))  # b'\xe8\xbf\x99\xe6\xac\xa1\xe5\x8f\xaf\xe4\xbb\xa5\xe4\xba\x86'
        time.sleep(1)
        if data.decode() == 'exit' or not data:
            print('{0} connection close'.format(addr))
            conn.send(bytes('Connection closed!'), 'UTF-8')
            break
        conn.send(bytes('Hello, {0}'.format(data), "UTF-8"))  # TypeError: a bytes-like object is required, not 'str'
    conn.close()


if __name__ == '__main__':
    socket_service()
2. 通过socketserver模块创建server端

socketserver模块是Python标准库中的一个模块。它提供了一个简单的接口,可以方便地创建TCP和UDP服务器,支持多线程处理客户端连接。

import socketserver
import threading


# 创建一个TCP服务器
class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        # 接收客户端数据
        recv_data = self.request.recv(1024).strip()
        print(recv_data.decode())

        # 发送数据到客户端
        send_data = 'hello'
        self.request.sendall(send_data.encode())


if __name__ == '__main__':
    with socketserver.ThreadingTCPServer(('127.0.0.1', 6668), MyTCPHandler) as server:
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.start()

client端

步骤:

1. 创建socket对象 s=socket.socket()

2. 连接server端 s.connect((ip,port))  #参数是元组

3. 发送/接受消息 s.send s.recv

import socket
import sys


def socket_client():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(('127.0.0.1', 6668))
    except socket.error as msg:
        print(msg)
        sys.exit(1)
    print(s.recv(1024))  # 目的在于接受
    while 1:
        data = input('please input work: ').encode()
        s.send(data)
        print('aa', s.recv(1024).decode())
        if data == 'exit':
            break
    s.close()


if __name__ == '__main__':
    socket_client()

websocket案例

server端

通过websockets模块创建server端

import asyncio
import websockets
from websockets.legacy.server import WebSocketServerProtocol


async def ws_handle(websocket: WebSocketServerProtocol, path: str):
    async for message in websocket:
        print(f"客户端发送的信息为:{message}")
        await websocket.send(message)
        # print("send over")

async def main():
    async with websockets.serve(ws_handle, "localhost", 8080):
        await asyncio.Future()              # run forever

if __name__ == "__main__":
    asyncio.run(main())

client端

1. 通过websockets模块创建客户端:
import asyncio
import websockets


async def main():
    async with websockets.connect("ws://localhost:8080") as websocket:
        # websocket: 
        await websocket.send("Hello World")
        msg = await websocket.recv()
        print(msg)


asyncio.run(main())
2. 通过websocket模块创建客户端:
import threading
import websocket

url = "ws://localhost:8080/websocket/546"

class WsClient(object):
    url = None
    ws = None

    def __init__(self, url):
        self.url = url

    def on_open(self,ws):
        print("WebSocket连接已建立")
        # 通过线程开始接收键盘输入,并send
        t = threading.Thread(self.run())
        t.start()

    def on_message(self, ws, message):
        print("接收到服务器发送的消息:%s" % message)

    def on_error(self, ws, error):
        print("WebSocket连接出错:%s" % error)

    def on_close(self, ws):
        print("WebSocket连接已关闭")

    def run(self):
        print("start run-开启线程接受键盘输入")
        while True:
            send_msg = input("我:")
            # print(f"信息为:{send_msg}")
            self.ws.send(send_msg)

    def start(self):
        # websocket.enableTrace(True)
        # self.ws = websocket.WebSocketApp(self.url)
        # self.ws.on_open = self.on_open
        # self.ws.on_error = self.on_error
        self.ws = websocket.WebSocketApp(self.url,
                                         on_open=self.on_open,
                                         on_message=self.on_message,
                                         on_close=self.on_close,
                                         on_error=self.on_error)
        self.ws.run_forever()


if __name__ == "__main__":
    ws = WsClient(url)
    ws.start()

你可能感兴趣的:(python实用笔记,websocket,网络协议,python)