嘘~ 正在从服务器偷取页面 . . .

多线程FTP(1)——多线程网络通信简单实现


多线程FTP(1)——多线程网络通信简单实现

之前写了一个FTP项目,但实际上我们写的FTP项目只满足单线程——这就像是打电话一样,当一个客户端和服务端连接,其他客户端就会因为服务端占线而无法连接,必须等之前连接的客户端“挂断”才能连接通信。

就像演示的一样,

  1. 当一个客户端完成连接(比如说登录,和查看当前目录时)
  2. 另一个客户端无法完成和服务端的通信,比如说登录;
  3. 而只有在前一个客户端断开连接,服务端才会去处理后一个客户端的信息(即完成登录)

很显然,一次只满足一个用户登录并不满足我们需求,我们想要的肯定是可以允许多个用户登录,服务端同时处理多个用户命令的FTP项目。

于是,我们想到了多线程的的方法去实现多个用户同时登录。

什么是多线程

多线程

threading ,利用 CPU 和 IO 可以同时执行的原来,让 CPU 不会干巴巴等待 IO 完成。

个人理解

单线程

多线程

简单来说,多线程就是一个计算机的统筹处理事情的操作,遇到需要等待的事情,就“先去”(在等待的同时)做可以即时做的事情。(理论上,多线程会增加CPU的内存和计算操作,但具体会增加多少,我没有研究过)

thread 版本

服务端

import socket, threading, time

def create():
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    server.bind(("127.0.0.1", 8080))

    server.listen(5)

    while True: # 连接循环
        conn, addr = server.accept()

        t = threading.Thread(target=connection, args=(conn, ))
        t.start()

def connection(conn):
        while True: # 通信循环
            data = conn.recv(1024)
            print(data.decode("utf-8"))

            now = time.localtime()
            now_time = time.strftime("%Y年%m月%d日%H时%M分%S秒", now)
            conn.send(now_time.encode("utf-8"))

# args 是函数的参数,如果有参数,传入的一定是一个元组
t = threading.Thread(target=create)
t.start() # 不要忘记 start,表示启动线程

客户端

客户端没有什么变化

import socket, time

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect(("127.0.0.1", 8080))

while True:
    cmd = input(">>: ").strip()

    client.send(cmd.encode("utf-8"))

    time.sleep(10) # 休息10秒,为了更好的演示,客户端B 并没有休眠 10 秒

    data = client.recv(1024)
    print(data.decode("utf-8"))

socketserver 版本

服务端

import socketserver,time

class server(socketserver.BaseRequestHandler):
    def handle(self) -> None: # 一定要是 handle
        print(self.request) # 相当于 conn
        print(self.client_address) # 相当于 addr

        while True: # 通信循环
            msg = self.request.recv(1024)
            now = time.localtime()
            now_time = time.strftime("%Y年%m月%d日%H时%M分%S秒", now)
            print(msg.decode("utf-8"), now_time)

            now = time.localtime()
            now_time = time.strftime("%Y年%m月%d日%H时%M分%S秒", now)
            self.request.send(now_time.encode("utf-8"))

s = socketserver.ThreadingTCPServer(("127.0.0.1", 8080), server) # 开启 TCP服务 多线程
s.serve_forever()

客户端

没有什么变化。


文章作者: New Ass
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 New Ass !
  目录