python socket示例

最近寫了一個socket示例,可以實(shí)現(xiàn)兩個功能:

  1. 一個服務(wù)端同時服務(wù)多個客戶端:采用帶返回值的多線程

2.客戶端發(fā)現(xiàn)服務(wù)端斷開后,自動重連

Server端代碼

import socket
import threading
import time


class MyThread(threading.Thread):
    """多線程有返回值時,使用該類"""
    def __init__(self, func, args=()):
        super(MyThread, self).__init__()
        self.func = func
        self.args = args

    def run(self):
        self.result = self.func(*self.args)

    def get_result(self):
        try:
            return self.result
        except Exception:
            return None


def recv_data(sock, nonblock_mark):
    if nonblock_mark:
        '''非阻塞式接受信息'''
        print("start to get message unblock")
        try:
            data = sock.recv(1024, 0x40)
        except Exception as e:
            print("no message recieved!!", e, "will recieve 3s later")
            time.sleep(3)
            data ="null"
    else:
        '''阻塞式接受信息'''
        print("start to get message block")
        try:
            data = sock.recv(1024)
        except Exception as e:
            print("connection broken!!!", e)
            data = None

    return data


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) #設(shè)置端口復(fù)用
s.bind(('', 123456))
s.listen(5)
print("waiting for connection!!!")
while True:
    sock, addr = s.accept()
    print("receive connection from %s:%s" % addr)
    while True:
        t = MyThread(recv_data, args=((sock, 1)))
        t.start()
        t.join()
        data = t.get_result()
        print(data)
        print("length of data:", len(data), time.time())
        if data == 'exit' or not data:
            print("connection from %s:%s closed" % addr)
            sock.close()
            break
        elif data == "null":
            print("receieve no data on nonblocking mode!!")
            continue
        
s.close()

Client端代碼

# 導(dǎo)入 socket、sys 模塊
import socket
import struct
import time


def doConnect(host, port):
    # 創(chuàng)建 socket 對象
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    while True:
        try:
            s.connect((host, port))
        except Exception as e:
            print("connection broken:", e, "will reconnect 3s later!!")
            time.sleep(3)
        else:
            break
    return s

# 獲取本地主機(jī)名
host = "127.0.0.1"
# 設(shè)置端口號
port = 123456
# 連接服務(wù),指定主機(jī)和端口
s = doConnect(host, port)

while True:
    data = input("please input anykey to continue:")
    if task_type:
        # 發(fā)送消息:如果連接失敗,重連服務(wù)器,重新發(fā)送
        try:
            s.send(data.edcode())
        except socket.error as e:
            print("connection borken:", e, "\nwill reconnect 3s later")
            s = doConnect(host, port)
            s.send(data)

    else:
        continue
s.close()

當(dāng)然,這段代碼也是有缺陷的:
1.標(biāo)準(zhǔn)代碼應(yīng)該采用類的方式來寫,本人類的基礎(chǔ)比較弱,有待加強(qiáng)
2.一個服務(wù)端同時服務(wù)多個客戶端,官方推薦采用select模塊
3.客戶端的自動重連功能有缺陷:當(dāng)服務(wù)端斷開30s之內(nèi),客戶端依然認(rèn)為服務(wù)端在線,這個bug暫時沒找到解決方案

參考資料:
python-socket客戶端設(shè)置自動重連,服務(wù)端線程收發(fā)消息
Python socket 怎么判斷連接斷開
Python-select詳解(select、epoll)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容