使用Socket與多線程實(shí)現(xiàn)聊天室

版本:Python3
知識(shí)點(diǎn):Socket,threading

一、服務(wù)器端

1作郭,服務(wù)器綁定地址與端口號(hào)陨囊,保持監(jiān)聽(tīng)狀態(tài)。
2夹攒,無(wú)限循環(huán)接收客戶端的連接蜘醋,驗(yàn)證身份判斷是否是客戶端,如果不是立即關(guān)閉連接咏尝,如果是則創(chuàng)建一個(gè)新線程管理對(duì)客戶端的所有操作压语,并將其加入到連接池。
3编检,當(dāng)客戶端主動(dòng)終止連接時(shí)胎食,通知其他用戶其已離開(kāi)聊天室,關(guān)閉連接允懂,從連接池里將其剔除厕怜。

運(yùn)行演示.png

代碼:

# encoding: utf-8
# Author: Timeashore
# Time: 2017-12-31
# Email: 1274866364@qq.com

# 服務(wù)器端
import threading
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1',5000))
s.listen(5)

print('Server',socket.gethostbyname('127.0.0.1'),'listening ...')
mydict = dict()     # fileno:nickname
mylist = list()     # 連接池列表

# 向在線人發(fā)送消息(除了發(fā)消息本人)
def send_everybody(number, message):
    for user in mylist:
        if user.fileno() != number:
            user.send(message.encode())


# 每個(gè)線程的調(diào)用方法,管理對(duì)客戶端的所有操作
def fun(conn, number):
    mylist.append(conn) # 添加到連接池
    nickname = conn.recv(1024).decode()
    conn.send(('Hello,'+nickname).encode())
    mydict[number] = nickname # 添加到fileno:nickname
    print('connection',number,'has nickname : ',nickname)   # 打印鏈接信息
    send_everybody(number, '【系統(tǒng)提示:'+nickname+' 進(jìn)入聊天室】')
    while True:
        try:
            conn.send(''.encode())
            getmessage = conn.recv(1024).decode()
            if getmessage:
                print(nickname,':',getmessage)
                send_everybody(number,nickname+': '+getmessage)
        except (OSError, ConnectionResetError):
            try:
                mylist.remove(conn)   # 從連接池列表剔除
            except:
                pass
            print(nickname, 'exit, ', len(mylist), ' person left')  # 服務(wù)器終端打印離開(kāi)信息
            send_everybody(number, '【系統(tǒng)提示:' + nickname + ' 離開(kāi)聊天室】')  # 告知所有人nickname已經(jīng)離開(kāi)聊天室
            conn.close()  # 關(guān)閉連接
            return

while True:
    conn, addr = s.accept()
    print('Accept new connection',conn.getsockname(),conn.fileno())
    try:
        verification = conn.recv(1024).decode()
        if verification == 'user':
            conn.send('welcome to server!\n'.encode())
            conn.send('nickname:\n'.encode())
            t = threading.Thread(target=fun, args=(conn, conn.fileno()))
            t.setDaemon(True)
            t.start()
        else:
            conn.send('Your verification NOT pass'.encode())
            conn.close()
    except:
        pass

二蕾总、客戶端

與服務(wù)器端相比粥航,客戶端比較簡(jiǎn)單。
1谤专,與服務(wù)器建立連接躁锡,發(fā)送身份驗(yàn)證信息。
2置侍,啟動(dòng)兩個(gè)線程映之,一個(gè)發(fā)送消息,一個(gè)接收消息蜡坊。

用戶1.png
用戶2.png

代碼:

# encoding: utf-8
# Author: Timeashore
# Time: 2017-12-31
# Email: 1274866364@qq.com


import socket
import threading

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1',5000))

s.send('user'.encode())  # 驗(yàn)證身份
print(s.recv(1024).decode()) # 接受歡迎消息
print(s.recv(1024).decode()) # 接受歡迎消息
nickname = input()
s.send(nickname.encode())

# 接收消息
def recv():
    while True:
        try:
            message = s.recv(1024).decode()
            if message:
                print(message)
            else:
                pass
        except ConnectionAbortedError:
            print('Server closed this connection!')
        except ConnectionResetError:
            print('Server is closed!')

# 發(fā)送消息
def send():
    while True:
        try:
            ready_send = input('')
            s.send(ready_send.encode())
        except ConnectionAbortedError:
            print('Server closed this connection!')
        except ConnectionResetError:
            print('Server is closed!')

# 啟動(dòng)兩個(gè)線程杠输,一個(gè)發(fā)送一個(gè)接收
t1 = threading.Thread(target=recv)
t2 = threading.Thread(target=send)

for x in [t1,t2]:
    x.setDaemon(True)
    x.start()
t1.join()
t2.join()

以上是在終端運(yùn)行,可以使用Python GUI工具 Tkinter 給客戶端增加一個(gè)界面秕衙,客戶端收到的消息實(shí)時(shí)顯示在界面上蠢甲,需要處理線程和GUI的配合。


GUI客戶端.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末据忘,一起剝皮案震驚了整個(gè)濱河市鹦牛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌勇吊,老刑警劉巖曼追,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異汉规,居然都是意外死亡礼殊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)晶伦,“玉大人碟狞,你說(shuō)我怎么就攤上這事』榕悖” “怎么了族沃?”我有些...
    開(kāi)封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)泌参。 經(jīng)常有香客問(wèn)我竭业,道長(zhǎng),這世上最難降的妖魔是什么及舍? 我笑而不...
    開(kāi)封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮窟绷,結(jié)果婚禮上锯玛,老公的妹妹穿的比我還像新娘。我一直安慰自己兼蜈,他們只是感情好攘残,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著为狸,像睡著了一般歼郭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辐棒,一...
    開(kāi)封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天病曾,我揣著相機(jī)與錄音,去河邊找鬼漾根。 笑死泰涂,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的辐怕。 我是一名探鬼主播逼蒙,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寄疏!你這毒婦竟也來(lái)了是牢?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎辙纬,沒(méi)想到半個(gè)月后塘安,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹈胡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罚渐。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡却汉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荷并,到底是詐尸還是另有隱情合砂,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布源织,位于F島的核電站翩伪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谈息。R本人自食惡果不足惜缘屹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望侠仇。 院中可真熱鬧轻姿,春花似錦、人聲如沸逻炊。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)余素。三九已至豹休,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間桨吊,已是汗流浹背威根。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屏积,地道東北人医窿。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像炊林,于是被迫代替她去往敵國(guó)和親姥卢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理渣聚,服務(wù)發(fā)現(xiàn)独榴,斷路器,智...
    卡卡羅2017閱讀 134,637評(píng)論 18 139
  • 18.1 引言 TCP是一個(gè)面向連接的協(xié)議奕枝。無(wú)論哪一方向另一方發(fā)送數(shù)據(jù)之前棺榔,都必須先在雙方之間建立一條連接。本章將...
    張芳濤閱讀 3,351評(píng)論 0 13
  • 1.OkHttp源碼解析(一):OKHttp初階2 OkHttp源碼解析(二):OkHttp連接的"前戲"——HT...
    隔壁老李頭閱讀 20,826評(píng)論 24 176
  • 你倆處對(duì)象了
    show7閱讀 98評(píng)論 0 0
  • 秋陽(yáng)少義寒蟬渴隘道, 玉月多情探舊檐症歇。 河漢虛懸星影怯郎笆, 破書安枕入鄉(xiāng)關(guān)。
    劉志堅(jiān)閱讀 396評(píng)論 0 7