Python TCPServer 多线程多客户端通信

Python ThreadingTCPServer 多线程多客户端通信自动重连

最简单、原始的TCP通信demo

服务端Http请求:

import socket

# 创建一个servicesocke
serviceSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 给服务器绑定地址(ip地址,端口号)
serviceSocket.bind(("192.168.171.1", 80))

print("等待客户端接入")
# sock 是客户端的socket信息
# addr 是客户端的地址(ip,端口)
sock, addr = serviceSocket.accept()
print(f"sock from client:{sock}")
print(f"addr of client:{addr}")

while True:
    # 接收客户端的请求
    recvData = sock.recv(1024)
    print("客户端说:%s" % (recvData.decode("utf-8")))
    sendData = input("服务器说:")
    # 发送(回复)数据给客户端
    sock.send(sendData.encode("utf-8"))

客户端Http请求:

import socket

# 创建客户端socket
clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接服务器
clientSocket.connect(("192.168.171.1", 80))

while True:
    # 发送消息给服务器
    sendData = input("客户端说:")
    if sendData == "bye":
        clientSocket.send(sendData.encode("utf-8"))  # 编码:将数据装换成二进制形式
        break
    clientSocket.send(sendData.encode("utf-8"))
    recvData = clientSocket.recv(1024)
    print("服务器说:%s" % (recvData.decode("utf-8")))  # 解码:将二进制转换成字符

1、在TCP中,客户端的实现流程:

  1. 创建客户端的socket对象
  2. 建立与服务器之间的联系
  3. 发送请求
  4. 接收数据
  5. 关闭连接

2、服务端的实现流程:

  1. 创建服务端的socket对象
  2. 绑定服务端的地址
  3. 设置监听器
  4. 等待客户端的连接
  5. 接收客户端的请求
  6. 返回处理的结果到客户端

ThreadingTCPServer 多线程多客户端通信自动重连demo

socketserver继承图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RP9L9E1X-1577626400313)(../../../markdown_pic/blog_socketserver.png)]


TCPServer
# from socketserver import TCPServer, BaseRequestHandler, ThreadingTCPServer
from socketserver import TCPServer, StreamRequestHandler, ThreadingMixIn
import traceback

# class MyBaseRequestHandler(BaseRequestHandler):
class MyBaseRequestHandler(StreamRequestHandler):

    def handle(self):
        self.addr = self.request.getpeername()
        self.server.users[self.addr[1]] = self.request
        message = "IP " + self.addr[0] + ":" + str(self.addr[1]) + " Connected..."
        print(message)

        while True:
            try:
                data = self.request.recv(1024).decode('UTF-8', 'ignore').strip()
                print(f'receive from {self.client_address}:{data}')

                back_data = (f"response\"" + data + "\":\n").encode("utf8")
                self.request.sendall(back_data)
            except:
                traceback.print_exc()
                break

# 源码:class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
# 从ThreadingMixIn和TCPServer继承,实现多线程
class MyThreadingTCPServer(ThreadingMixIn, TCPServer):
    def __init__(self, server_address, RequestHandlerClass):
        TCPServer.__init__(self, server_address, RequestHandlerClass)
        self.users = {}


class MyTCPserver():
    def __init__(self, server_addr='192.168.1.109', server_port=23):
        self.server_address = server_addr
        self.server_port = server_port
        self.server_tuple = (self.server_address, self.server_port)

    def run(self):
        # server = TCPServer(self.server_tuple, MyBaseRequestHandler)
        server = MyThreadingTCPServer(self.server_tuple, MyBaseRequestHandler)
        server.serve_forever()


if __name__ == '__main__':
    myserver = MyTCPserver()
    myserver.run()

在telnet 下开启开启两个客户端,本电脑的IP为192.168.1.109,开两个客户端后,TCPServer的终端出现同一个IP但是不同端口的连接:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LRSXfXoG-1577626400318)(../../../markdown_pic/blog_TCPServer.png)]


TCPClient
import socket
import time

class MyClient:
    host = '192.168.1.109'
    port = 23
    bufsiz = 1024
    addr = None
    skt = None

    def __init__(self, host=None, port=None):
        if host != None:
            self.host = host

        if port != None:
            self.port = port

        if self.addr == None:
            self.addr = (self.host, self.port)

        self.doConnection()

    def doConnection(self):
        try:
            self.skt = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.skt.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
            print(self.addr)
            self.skt.connect(self.addr)
        except:
            pass

    def run(self):
        while True:
            try:
                _time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
                self.skt.sendall(f'{_time}:i am clent1 '.encode('utf-8'))
                data = self.skt.recv(self.bufsiz)
                print(data.decode('utf-8', 'ignore'))
                if not data:
                    break
                print(data.strip())
                time.sleep(5)
            except socket.error:
                print('socket error, reconnection')  # 自动重连
                time.sleep(3)
                self.doConnection()
            except:
                print('other error')

        self.skt.close()


myclient = MyClient()
myclient.run()

上面用的是telnet工具来作为客户端,这里是用代码实现模拟的客户端。
在这里插入图片描述

多线程TCP双向通信Python是指使用Python编写程序,通过Socket套接字实现多个客户端与服务端之间的双向通信,并且使用多线程技术实现同时连接多个客户端的程序。具体实现过程如下: 1. 服务端创建一个Socket对象,绑定IP地址和端口号,并监听客户端的连接请求。 2. 客户端创建一个Socket对象,连接服务端的IP地址和端口号。 3. 服务端接收到客户端的连接请求后,创建一个新的线程处理该客户端的请求。 4. 客户端向服务端发送数据,服务端接收到数据后进行处理,并向客户端发送响应数据。 5. 客户端接收到服务端的响应数据后进行处理。 下面是一个简单的多线程TCP双向通信Python的示例代码: ```python # 服务端代码 import socket import threading def handle_client(client_socket, client_address): while True: data = client_socket.recv(1024) if not data: break print("Received data from {}: {}".format(client_address, data.decode())) client_socket.send("Hello, client!".encode()) client_socket.close() def main(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('127.0.0.1', 8888)) server_socket.listen(5) print("Server is listening on {}:{}".format('127.0.0.1', 8888)) while True: client_socket, client_address = server_socket.accept() print("Accepted connection from {}:{}".format(client_address[0], client_address[1])) client_thread = threading.Thread(target=handle_client, args=(client_socket, client_address)) client_thread.start() if __name__ == '__main__': main() # 客户端代码 import socket def main(): client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('127.0.0.1', 8888)) while True: data = input("Please input data to send to server: ") client_socket.send(data.encode()) response = client_socket.recv(1024) print("Received response from server: {}".format(response.decode())) if __name__ == '__main__': main() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值