python socket多線程實現客戶端與服務器連接

python socket多線程實現客戶端與服務器連接,供大傢參考,具體內容如下

之前因為一些作業需要完成一個服務器監聽多個客戶端的程序,於是就用python寫瞭這樣的程序。話不多說,直接上代碼。

server代碼:

import json
import socket
import threading
import time
import struct

class Server():
    def __init__(self):
        self.g_conn_pool = {}  # 連接池
        # 記錄客戶端數量
        self.num =0
        # 服務器本地地址
        self.address = ('0.0.0.0', 8000)
        # 初始化服務器
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server_socket.bind(self.address)
        self.server_socket.listen(128)
    def accept_client(self):
        """
            接收新連接
            """
        while True:
            client_socket, info = self.server_socket.accept()  # 阻塞,等待客戶端連接
            print(client_socket,port)
            # 給每個客戶端創建一個獨立的線程進行管理
            thread = threading.Thread(target=self.recv_msg, args=(client_socket,info))
            thread.setDaemon(True)
            thread.start()
    def recv_msg(self,client,info):
        # 提示服務器開啟成功
        print('服務器已準備就緒!')
        client.sendall("connect server successfully!".encode(encoding='utf8'))
        # 持續接受客戶端連接
        while True:
            try:
                client.sendall(b'Success')
                while True:
                    msg = client.recv(1024)
                    msg_recv = msg.decode('utf-8')
                    if not msg_recv:
                        continue
                    else:
                        recv_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
                        print('客戶端 ' + recv_time + ':\n')
                        print(' ' + msg_recv + '\n')
            except Exception as e:

                print('客戶端斷開連接...')
                exit(-1)
                break
    def start_new_thread(self):
        """啟動新線程來接收信息"""
        thread = threading.Thread(target=self.accept_client, args=())
        thread.setDaemon(True)
        thread.start()

server服務器類,主要是監聽以及接收客戶端的信息。

#實例化一個Flask節點
app = Flask(__name__)


@app.route('/')
def hello():
    return 'hello'


if __name__ == '__main__':
 #創建解析器
    from argparse import ArgumentParser
    parser = ArgumentParser()
    parser.add_argument('-p', '--port', default=5030, type=int, help='port to listen on')
    args = parser.parse_args()
    #獲取端口號
    port = args.port
    #實例化一個server類 並啟動
    py_server = Server()
    py_server.start_new_thread()
    #啟動Flask節點
    app.run(host='127.0.0.1',port=port)

Client代碼

class Client():

    def __init__(self):
     #服務器ip與端口
        self.server_address = ('127.0.0.1', 8000)
        
        self.num = 0
    def recv_msg(self):
        print("正在連接服務器....")

        # 客戶端連接服務器
        while True:
            try:
                self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                #連接服務器
                self.client_socket.connect(self.server_address)

                num = self.num

                # 制作報頭
                header_dic = {
                    'filename': num
                }
                header_bytes = json.dumps(header_dic).encode('utf-8')
                self.client_socket.send(struct.pack('i', len(header_bytes)))
                self.client_socket.send(header_bytes)
                
    #接收信息
                while True:
                    msg_recv = self.client_socket.recv(1024).decode('gbk')
                    print(msg_recv)

                    if msg_recv == 'Success':
                        print('客戶端已與服務器成功建立連接...')
                    elif not msg_recv:
                        continue
                    else:
                        recv_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
                        print( '服務器 ' + recv_time + ':\n')
                        print(' ' + msg_recv + '\n')

            except:
                print('與服務器斷開連接...')
                break
    def start_new_thread(self):
        """啟動新線程來接收信息"""
        thread = threading.Thread(target=self.recv_msg, args=())
        thread.setDaemon(True)
        thread.start()
        
def main():
    wf = Client()
    wf.start_new_thread()
 while True:
        a = input()
        wf.client_socket.send(a.encode('utf-8'))

if __name__ == '__main__':

    main()

以上為客戶端程序的代碼。

下面是運行的結果:

服務器端:

多個客戶端:

代碼實現還是蠻容易的,具體可以自行修改使用。

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: