python使用socket制作聊天室詳細(xì)源碼(可以直接運(yùn)行)
python 使用socket制作聊天室
1.基本前提
為什么socket能做聊天室呢
1、socket提供了通信的服務(wù) 比如你可以創(chuàng)建tcp udp的請(qǐng)求 向某個(gè)主機(jī)發(fā)起通信
就像是你想和某人說(shuō)話 你得會(huì)發(fā)音
2、就是提供了服務(wù)端的方式和客戶端的方式
服務(wù)端處理用戶發(fā)起的請(qǐng)求
客戶端發(fā)送數(shù)據(jù)和接收服務(wù)端的響應(yīng)數(shù)據(jù)
就像你打開(kāi)瀏覽器看視頻 你作為客戶端 發(fā)起請(qǐng)求 在某處的服務(wù)端(web服務(wù)器)會(huì)把請(qǐng)求接受處理
返回相應(yīng)的數(shù)據(jù) 通過(guò)瀏覽器(客戶端)接受解析 就變成了看的見(jiàn)的網(wǎng)頁(yè)數(shù)據(jù)
想搞定聊天室
1.需要一個(gè)服務(wù)端提供下服務(wù)
- 時(shí)刻接受鏈接進(jìn)來(lái)的用戶
- 接受用戶的發(fā)送信息
- 對(duì)所有的用戶發(fā)送廣播 這樣都能收到
2.需要多個(gè)客戶端
1.鏈接進(jìn)入聊天室
2.發(fā)送數(shù)據(jù)
3.接受廣播數(shù)據(jù)
基本關(guān)系
2.服務(wù)端的搭建
1.導(dǎo)入socket包
創(chuàng)建通訊tcp等請(qǐng)求
導(dǎo)入threading包 使用線程來(lái)處理那些請(qǐng)求數(shù)據(jù)
import socket import threading #全局變量 SERVER_HOST = 'localhost' SERVER_PORT = 8000 BUFFER_SIZE = 1024
2.創(chuàng)建socket的實(shí)例
tcp通信對(duì)象
socket.AF_INET, socket.SOCK_STREAM 是創(chuàng)建tcp的參數(shù)
百度可以了解更多 比如udp等
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
3.綁定端口
服務(wù)的套接字 也就是IP地址+端口號(hào)
server_socket.bind((SERVER_HOST, SERVER_PORT)) server_socket.listen(5) # 監(jiān)聽(tīng) 最大可以鏈接的數(shù)量
4.進(jìn)入循環(huán)中 等待客戶端的鏈接
while True: client_socket, addr = server_socket.accept()
5.把鏈接的客戶存放起來(lái)
# 存放鏈接進(jìn)來(lái)聊天的用戶 clients = [] while True: client_socket, addr = server_socket.accept() clients.append(client_socket)
使用線程 給進(jìn)入的用戶分配處理函數(shù)
# 開(kāi)啟線程 handle_client處理函數(shù) client_socket 參數(shù) thread = threading.Thread(target=handle_client, args=(client_socket,)) thread.start()
handle_client的定義
1.客戶端第一次進(jìn)來(lái) 需要輸入自己的名稱
def handle_client(client_socket): """處理客戶端連接""" name = client_socket.recv(BUFFER_SIZE).decode()#接受客戶端發(fā)來(lái)的名稱 print(f'[*] {name} 已連接')#服務(wù)端打印查看 welcome = f'歡迎來(lái)到聊天室, {name}!\n'.encode() client_socket.send(welcome)#返回給客戶端 歡迎的信息
2.循環(huán) 等待用戶的連天數(shù)據(jù)發(fā)送
while True: msg = client_socket.recv(BUFFER_SIZE)#接受用戶發(fā)來(lái)的消息 比如 你好 #處理用戶的退出 if msg.decode() == 'quit': print(f'[*] {name} 斷開(kāi)連接') client_socket.close() break #向聊天室的所有人廣播 broadcast(msg, name)
broadcast定義
clients 所有的鏈接客戶
發(fā)送誰(shuí)說(shuō)了什么
send(f’{name}: {msg.decode()}'.encode())
encode 是轉(zhuǎn)碼的意思
decode 是解碼的意思
def broadcast(msg, name): """向所有已連接的客戶端廣播消息""" for client in clients: client.send(f'{name}: {msg.decode()}'.encode())
服務(wù)端總結(jié):
- 創(chuàng)建一個(gè)tcp的服務(wù)端
- 把鏈接的用戶存放起來(lái)
- 第一次接受用戶名字
- while循環(huán)接受發(fā)送的信息并廣播出去
3. 客戶端的搭建
引入socket包
引入threading包
import socket import threading #全局變量 SERVER_HOST = 'localhost' SERVER_PORT = 8000 BUFFER_SIZE = 1024
創(chuàng)建一個(gè)tcp通信
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
發(fā)起連接
client_socket.connect((SERVER_HOST, SERVER_PORT))
發(fā)送自己的昵稱
name = input('請(qǐng)輸入您的昵稱: ') # 發(fā)送昵稱 name_bytes = name.encode() client_socket.send(name_bytes)
開(kāi)啟線程進(jìn)行聊天的處理
# 開(kāi)啟線程用來(lái)接收服務(wù)器發(fā)送的消息 thread_output = threading.Thread(target=handle_output, args=(client_socket,)) thread_output.start() # 開(kāi)啟線程用來(lái)處理用戶輸入的消息 thread_input = threading.Thread(target=handle_input, args=(client_socket,)) thread_input.start()
handle_input的定義
輸入要發(fā)送的信息
def handle_input(client_socket): """處理用戶輸入""" while True: msg = input('')#輸入要發(fā)送的信息 client_socket.send(msg.encode()) if msg == 'quit':#退出處理 break
handle_output的定義
接受廣播的數(shù)據(jù)展示出來(lái)
def handle_output(client_socket): """處理消息輸出""" while True: msg = client_socket.recv(BUFFER_SIZE)#接收數(shù)據(jù) if msg.decode() == 'quit': break print(msg.decode())#展示
客戶端總結(jié)
- 發(fā)起連接
- 進(jìn)行昵稱發(fā)送
- 發(fā)送信息
- 接受廣播信息
4 完整的源碼分享
服務(wù)端
import socket import threading SERVER_HOST = '0.0.0.0' SERVER_PORT = 8000 BUFFER_SIZE = 1024 def handle_client(client_socket): """處理客戶端連接""" name = client_socket.recv(BUFFER_SIZE).decode() print(f'[*] {name} 已連接') welcome = f'歡迎來(lái)到聊天室, {name}!\n'.encode() client_socket.send(welcome) while True: msg = client_socket.recv(BUFFER_SIZE) if msg.decode() == 'quit': print(f'[*] {name} 斷開(kāi)連接') client_socket.close() break broadcast(msg, name) def broadcast(msg, name): """向所有已連接的客戶端廣播消息""" for client in clients: client.send(f'{name}: {msg.decode()}'.encode()) if __name__ == '__main__': server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((SERVER_HOST, SERVER_PORT)) server_socket.listen(5) print(f'[*] 正在聽(tīng)取端口 {SERVER_PORT}') clients = [] while True: client_socket, addr = server_socket.accept() clients.append(client_socket) # 開(kāi)啟線程 thread = threading.Thread(target=handle_client, args=(client_socket,)) thread.start()
客戶端的代碼
import socket import threading SERVER_HOST = 'localhost' SERVER_PORT = 8000 BUFFER_SIZE = 1024 def handle_input(client_socket): """處理用戶輸入""" while True: msg = input('') client_socket.send(msg.encode()) if msg == 'quit': break def handle_output(client_socket): """處理消息輸出""" while True: msg = client_socket.recv(BUFFER_SIZE) if msg.decode() == 'quit': break print(msg.decode()) if __name__ == '__main__': name = input('請(qǐng)輸入您的昵稱: ') client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((SERVER_HOST, SERVER_PORT)) # 發(fā)送昵稱 name_bytes = name.encode() client_socket.send(name_bytes) # 開(kāi)啟線程用來(lái)接收服務(wù)器發(fā)送的消息 thread_output = threading.Thread(target=handle_output, args=(client_socket,)) thread_output.start() # 開(kāi)啟線程用來(lái)處理用戶輸入的消息 thread_input = threading.Thread(target=handle_input, args=(client_socket,)) thread_input.start()
5.實(shí)驗(yàn)測(cè)試
開(kāi)啟服務(wù)
客戶鏈接
服務(wù)檢測(cè)
在連接一個(gè)用戶
服務(wù)檢測(cè)
發(fā)送消息
廣播接受
這樣就能聊天了
代碼還有很多地方可以改進(jìn)
可以直接復(fù)制粘貼使用
總結(jié)
到此這篇關(guān)于python使用socket制作聊天室的文章就介紹到這了,更多相關(guān)python socket制作聊天室內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pytorch實(shí)現(xiàn)網(wǎng)絡(luò)部分層的固定不進(jìn)行回傳更新問(wèn)題及思路詳解
這篇文章主要介紹了Pytorch實(shí)現(xiàn)網(wǎng)絡(luò)部分層的固定不進(jìn)行回傳更新,實(shí)現(xiàn)思路就是利用tensor的requires_grad,每一個(gè)tensor都有自己的requires_grad成員,值只能為T(mén)rue和False,具體內(nèi)容詳情跟隨小編一起看看吧2021-08-08Python中執(zhí)行調(diào)用JS的多種實(shí)現(xiàn)方法總結(jié)
這篇文章主要給大家介紹了關(guān)于Python中執(zhí)行調(diào)用JS的多種實(shí)現(xiàn)方法,在一些特殊的python應(yīng)用場(chǎng)景下需要逆向執(zhí)行javascript代碼塊或者.js文件,需要的朋友可以參考下2023-08-08數(shù)組保存為txt, npy, csv 文件, 數(shù)組遍歷enumerate的方法
今天小編就為大家分享一篇數(shù)組保存為txt, npy, csv 文件, 數(shù)組遍歷enumerate的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07在Python的Django框架下使用django-tagging的教程
這篇文章主要介紹了在Python的Django框架下使用django-tagging的教程,針對(duì)網(wǎng)絡(luò)編程中的tag部分功能提供幫助,需要的朋友可以參考下2015-05-05對(duì)Python發(fā)送帶header的http請(qǐng)求方法詳解
今天小編就為大家分享一篇對(duì)Python發(fā)送帶header的http請(qǐng)求方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01使用Protocol Buffers的C語(yǔ)言拓展提速Python程序的示例
這篇文章主要介紹了使用Protocol Buffers的C語(yǔ)言拓展提速Python程序的示例,使用C拓展Python是Python編程進(jìn)階中的重要技巧,需要的朋友可以參考下2015-04-04Mac上Python使用ffmpeg完美解決方案(避坑必看!)
ffmpeg是一個(gè)強(qiáng)大的開(kāi)源命令行多媒體處理工具,下面這篇文章主要給大家介紹了關(guān)于Mac上Python使用ffmpeg完美解決方案的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02