首頁  >  文章  >  後端開發  >  Python下的socket程式設計

Python下的socket程式設計

高洛峰
高洛峰原創
2016-10-19 10:33:131261瀏覽

首先需要說明的一點是:這裡並不會記錄很深奧的socket編程,只是會分析一個最簡單的socket編程聊天室下的幾種特殊異常情況的處理,代碼如下:

服務端:

import socket

HOST = ""
PORT = 8870
sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.bind((HOST, PORT))
sk.listen(5)
while True:
    print("服务器启动")
    conn, addr = sk.accept()
    print(addr)
    while True:
        try:
            server_recv_data = conn.recv(1024)  #若客户端输入exit退出,则此处并没有阻塞,只是收到的信息为空
            #若客户端输入空,即直接按下回车键,那么此处将会被阻塞
            if len(server_recv_data) == 0:
                print("收到为空")
                break
        except ConnectionResetError as err:
            print(err)
            break
        print(str(server_recv_data, encoding="utf-8"))
        server_resp_data = input(">>>")
        conn.sendall(bytes(server_resp_data, encoding="utf-8"))
    conn.close()
sk.close()

客戶端:

import socket

HOST = "127.0.0.1"
PORT = 8870
sk = socket.socket()
sk.connect((HOST, PORT))
print("客户端启动...")

while True:
    inp = input(">>>")
    if inp == "exit"or not inp:  #此处需要说明的是,当直接在客户端按下回车enter键的时候,inp为空
        break
    sk.sendall(bytes(inp, encoding="utf-8"))
    server_response = sk.recv(1024)
    print(str(server_response, encoding="utf-8"))
sk.close()

注意:

1.當客戶端強行關閉的時候(比如在pycharm中按下調試窗口左端的stop按鈕時),客戶端當然會報錯,但是在Linux系統上,服務端不會報錯,只是認為接收到的資訊為空,即此處的server_recv_data為空,所以在此服務端做了一個判斷退出內層循環,以便可以連接其他的客戶端發送來的連接請求;

2.當客戶端輸入exit表示要退出目前聊天的時候,此處客戶端if判斷break退出,關鍵是此時的服務端得到的結果是,server_recv_data為空,與上面情況一樣;

3.唯一可以讓服務端的server-recv_data = conn.recv(1024)發生阻塞的是:客戶端直接按下回車,此時一個尷尬的情況是服務端仍然等待客戶端發送訊息(認為沒有訊息到來),客戶端無法再發送訊息,因為剛才已經按回車了,雖然可以再輸入訊息,但是無法發送了(即使再按回車也沒用),所以為了解決這個問題,我們默認認為當客戶端做出這個動作的時候表示要退出,此時inp為空,所以在客戶端做出了if not inp:的判斷,退出聊天,服務端收到為空,break之後繼續等待其他連接


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn