python 使用socket制作聊天室
1.基本前提
為什么socket能做聊天室呢
- socket提供了通信的服務(wù) 比如你可以創(chuàng)建tcp udp的請(qǐng)求 向某個(gè)主機(jī)發(fā)起通信
就像是你想和某人說話 你得會(huì)發(fā)音- 就是提供了服務(wù)端的方式和客戶端的方式
服務(wù)端處理用戶發(fā)起的請(qǐng)求
客戶端發(fā)送數(shù)據(jù)和接收服務(wù)端的響應(yīng)數(shù)據(jù)
就像你打開瀏覽器看視頻 你作為客戶端 發(fā)起請(qǐng)求 在某處的服務(wù)端(web服務(wù)器)會(huì)把請(qǐng)求接受處理
返回相應(yīng)的數(shù)據(jù) 通過瀏覽器(客戶端)接受解析 就變成了看的見的網(wǎng)頁(yè)數(shù)據(jù)
想搞定聊天室
1.需要一個(gè)服務(wù)端提供下服務(wù)
- 時(shí)刻接受鏈接進(jìn)來的用戶
- 接受用戶的發(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包 使用線程來處理那些請(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)聽 最大可以鏈接的數(shù)量
4.進(jìn)入循環(huán)中 等待客戶端的鏈接
while True:
client_socket, addr = server_socket.accept()
5.把鏈接的客戶存放起來
# 存放鏈接進(jìn)來聊天的用戶
clients = []
while True:
client_socket, addr = server_socket.accept()
clients.append(client_socket)
使用線程 給進(jìn)入的用戶分配處理函數(shù)
# 開啟線程
handle_client處理函數(shù)
client_socket 參數(shù)
thread = threading.Thread(target=handle_client, args=(client_socket,))
thread.start()
handle_client的定義
1.客戶端第一次進(jìn)來 需要輸入自己的名稱
def handle_client(client_socket):
"""處理客戶端連接"""
name = client_socket.recv(BUFFER_SIZE).decode()#接受客戶端發(fā)來的名稱
print(f'[*] {name} 已連接')#服務(wù)端打印查看
welcome = f'歡迎來到聊天室, {name}!\n'.encode()
client_socket.send(welcome)#返回給客戶端 歡迎的信息
2.循環(huán) 等待用戶的連天數(shù)據(jù)發(fā)送
while True:
msg = client_socket.recv(BUFFER_SIZE)#接受用戶發(fā)來的消息 比如 你好
#處理用戶的退出
if msg.decode() == 'quit':
print(f'[*] {name} 斷開連接')
client_socket.close()
break
#向聊天室的所有人廣播
broadcast(msg, name)
broadcast定義
clients 所有的鏈接客戶
發(fā)送誰說了什么
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ù)端
- 把鏈接的用戶存放起來
- 第一次接受用戶名字
- 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)
開啟線程進(jìn)行聊天的處理
# 開啟線程用來接收服務(wù)器發(fā)送的消息
thread_output = threading.Thread(target=handle_output, args=(client_socket,))
thread_output.start()
# 開啟線程用來處理用戶輸入的消息
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ù)展示出來
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'歡迎來到聊天室, {name}!\n'.encode()
client_socket.send(welcome)
while True:
msg = client_socket.recv(BUFFER_SIZE)
if msg.decode() == 'quit':
print(f'[*] {name} 斷開連接')
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'[*] 正在聽取端口 {SERVER_PORT}')
clients = []
while True:
client_socket, addr = server_socket.accept()
clients.append(client_socket)
# 開啟線程
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)
# 開啟線程用來接收服務(wù)器發(fā)送的消息
thread_output = threading.Thread(target=handle_output, args=(client_socket,))
thread_output.start()
# 開啟線程用來處理用戶輸入的消息
thread_input = threading.Thread(target=handle_input, args=(client_socket,))
thread_input.start()
5.實(shí)驗(yàn)測(cè)試
開啟服務(wù)
客戶鏈接
服務(wù)檢測(cè)
在連接一個(gè)用戶
服務(wù)檢測(cè)
發(fā)送消息
廣播接受
這樣就能聊天了文章來源:http://www.zghlxwxcb.cn/news/detail-720454.html
代碼還有很多地方可以改進(jìn)
可以直接復(fù)制粘貼使用文章來源地址http://www.zghlxwxcb.cn/news/detail-720454.html
到了這里,關(guān)于python 使用socket制作聊天室-(附帶 源碼 可以直接運(yùn)行)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!