欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python實(shí)現(xiàn)網(wǎng)絡(luò)聊天室的示例代碼(支持多人聊天與私聊)

 更新時(shí)間:2021年01月27日 11:35:50   作者:aaaadioppa  
這篇文章主要介紹了Python實(shí)現(xiàn)網(wǎng)絡(luò)聊天室的示例代碼(支持多人聊天與私聊),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

實(shí)驗(yàn)名稱(chēng):

網(wǎng)絡(luò)聊天室

功能:

i. 掌握利用Socket進(jìn)行編程的技術(shù)
ii. 掌握多線程技術(shù),保證雙方可以同時(shí)發(fā)送
iii. 建立聊天工具
iv. 可以和單人聊天
v. 可以和多個(gè)人同時(shí)進(jìn)行聊天
vi. 使用圖形界面,顯示雙方的語(yǔ)錄
vii. 程序可以在一定程度上進(jìn)行錯(cuò)誤識(shí)別

概述

實(shí)驗(yàn)通過(guò)聊天室可以完成單人或多人之間的聊天通信,功能的實(shí)現(xiàn)主要是通過(guò)Socket通信來(lái)實(shí)現(xiàn)。本次實(shí)驗(yàn)采用客戶(hù)端/服務(wù)器(C/S)架構(gòu)模式,通過(guò)Python語(yǔ)言來(lái)編寫(xiě)服務(wù)器端與客戶(hù)端的程序。運(yùn)用多線程可完成多點(diǎn)對(duì)多點(diǎn)的聊天。
服務(wù)器端程序主要用于接收用戶(hù)信息,消息接收與轉(zhuǎn)發(fā)。
客戶(hù)端程序?qū)崿F(xiàn)用戶(hù)注冊(cè)登錄,聊天信息顯示與信息輸入。

代碼解釋

統(tǒng)計(jì)當(dāng)前在線人數(shù),并且將新用戶(hù)加到用戶(hù)列表中。
Serve.py

在這里插入圖片描述

這是服務(wù)器對(duì)于聊天服務(wù)的實(shí)現(xiàn)。

在這里插入圖片描述

通過(guò)繼承threading.Thread類(lèi)而實(shí)現(xiàn)多線程,重寫(xiě)run函數(shù)。

在這里插入圖片描述

接受來(lái)自客戶(hù)端的用戶(hù)名,如果用戶(hù)名為空,使用用戶(hù)的IP與端口作為用戶(hù)名。如果用戶(hù)名出現(xiàn)重復(fù),則在出現(xiàn)的用戶(hù)名依此加上后綴“2”、“3”、“4”……

在這里插入圖片描述

在獲取用戶(hù)名后便會(huì)不斷地接受用戶(hù)端發(fā)來(lái)的消息(即聊天內(nèi)容),結(jié)束后關(guān)閉連接。

在這里插入圖片描述

如果用戶(hù)斷開(kāi)連接,將該用戶(hù)從用戶(hù)列表中刪除,然后更新用戶(hù)列表。

在這里插入圖片描述

將地址與數(shù)據(jù)(需發(fā)送給客戶(hù)端)存入messages隊(duì)列。

在這里插入圖片描述

服務(wù)端在接受到數(shù)據(jù)后,會(huì)對(duì)其進(jìn)行一些處理然后發(fā)送給客戶(hù)端,如下圖,對(duì)于聊天內(nèi)容,服務(wù)端直接發(fā)送給客戶(hù)端,而對(duì)于用戶(hù)列表,便由json.dumps處理后發(fā)送。

在這里插入圖片描述

Client.py
建立連接,發(fā)送用戶(hù)名及判斷是否為私聊消息,私聊用~識(shí)別

在這里插入圖片描述

接受來(lái)自服務(wù)器發(fā)送的消息

在這里插入圖片描述

對(duì)接收到的消息進(jìn)行判斷,如果是在線用戶(hù)列表(用json.dumps處理過(guò)),便清空在線用戶(hù)列表框,并將此列表輸出在在線用戶(hù)列表框中。

在這里插入圖片描述

如果是聊天內(nèi)容,便將其輸出在聊天內(nèi)容顯示框中。

在這里插入圖片描述

設(shè)置登錄窗口

在這里插入圖片描述

設(shè)置消息界面

在這里插入圖片描述

設(shè)置在線用戶(hù)列表。

在這里插入圖片描述

完整代碼:
Serve.py

import socket
import threading
import queue
import json # json.dumps(some)打包  json.loads(some)解包
import os
import os.path
import sys


IP = '127.0.0.1'
PORT = 9999   # 端口
messages = queue.Queue()
users = []  # 0:userName 1:connection
lock = threading.Lock()

def onlines():  # 統(tǒng)計(jì)當(dāng)前在線人員
  online = []
  for i in range(len(users)):
    online.append(users[i][0])
  return online

class ChatServer(threading.Thread):
  global users, que, lock

  def __init__(self):     # 構(gòu)造函數(shù)
    threading.Thread.__init__(self)
    self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    os.chdir(sys.path[0])
# 接受來(lái)自客戶(hù)端的用戶(hù)名,如果用戶(hù)名為空,使用用戶(hù)的IP與端口作為用戶(hù)名。如果用戶(hù)名出現(xiàn)重復(fù),則在出現(xiàn)的用戶(hù)名依此加上后綴“2”、“3”、“4”……
  def receive(self, conn, addr):       # 接收消息
    user = conn.recv(1024)    # 用戶(hù)名稱(chēng)
    user = user.decode()
    if user == '用戶(hù)名不存在':
      user = addr[0] + ':' + str(addr[1])
    tag = 1
    temp = user
    for i in range(len(users)):   # 檢驗(yàn)重名,則在重名用戶(hù)后加數(shù)字
      if users[i][0] == user:
        tag = tag + 1
        user = temp + str(tag)
    users.append((user, conn))
    USERS = onlines()
    self.Load(USERS,addr)
    # 在獲取用戶(hù)名后便會(huì)不斷地接受用戶(hù)端發(fā)來(lái)的消息(即聊天內(nèi)容),結(jié)束后關(guān)閉連接。
    try:
      while True:
        message = conn.recv(1024)      # 發(fā)送消息
        message = message.decode()
        message = user + ':' + message
        self.Load(message,addr)
      conn.close()
    # 如果用戶(hù)斷開(kāi)連接,將該用戶(hù)從用戶(hù)列表中刪除,然后更新用戶(hù)列表。
    except:  
      j = 0      # 用戶(hù)斷開(kāi)連接
      for man in users:
        if man[0] == user:
          users.pop(j)    # 服務(wù)器段刪除退出的用戶(hù)
          break
        j = j+1

      USERS = onlines()
      self.Load(USERS,addr)
      conn.close()

# 將地址與數(shù)據(jù)(需發(fā)送給客戶(hù)端)存入messages隊(duì)列。
  def Load(self, data, addr):
    lock.acquire()
    try:
      messages.put((addr, data))
    finally:
      lock.release()    

  # 服務(wù)端在接受到數(shù)據(jù)后,會(huì)對(duì)其進(jìn)行一些處理然后發(fā)送給客戶(hù)端,如下圖,對(duì)于聊天內(nèi)容,服務(wù)端直接發(fā)送給客戶(hù)端,而對(duì)于用戶(hù)列表,便由json.dumps處理后發(fā)送。
  def sendData(self): # 發(fā)送數(shù)據(jù)
    while True:
      if not messages.empty():
        message = messages.get()
        if isinstance(message[1], str):
          for i in range(len(users)):
            data = ' ' + message[1]
            users[i][1].send(data.encode())
            print(data)
            print('\n')

        if isinstance(message[1], list):
          data = json.dumps(message[1])
          for i in range(len(users)):
            try:
              users[i][1].send(data.encode())
            except:
              pass

  def run(self):
    self.s.bind((IP,PORT))
    self.s.listen(5)
    q = threading.Thread(target=self.sendData)
    q.start()
    while True:
      conn, addr = self.s.accept()
      t = threading.Thread(target=self.receive, args=(conn, addr))
      t.start()
    self.s.close()
if __name__ == '__main__':
  cserver = ChatServer()
cserver.start()

Client.py

import socket
import tkinter
import tkinter.messagebox
import threading
import json
import tkinter.filedialog
from tkinter.scrolledtext import ScrolledText

IP = ''
PORT = ''
user = ''
listbox1 = '' # 用于顯示在線用戶(hù)的列表框
show = 1 # 用于判斷是開(kāi)還是關(guān)閉列表框
users = [] # 在線用戶(hù)列表
chat = '------Group chat-------' # 聊天對(duì)象

#登陸窗口

root0 = tkinter.Tk()
root0.geometry("300x150")
root0.title('用戶(hù)登陸窗口')
root0.resizable(0,0)
one = tkinter.Label(root0,width=300,height=150,bg="LightBlue")
one.pack()

IP0 = tkinter.StringVar()
IP0.set('')
USER = tkinter.StringVar()
USER.set('')

labelIP = tkinter.Label(root0,text='IP地址',bg="LightBlue")
labelIP.place(x=20,y=20,width=100,height=40)
entryIP = tkinter.Entry(root0, width=60, textvariable=IP0)
entryIP.place(x=120,y=25,width=100,height=30)

labelUSER = tkinter.Label(root0,text='用戶(hù)名',bg="LightBlue")
labelUSER.place(x=20,y=70,width=100,height=40)
entryUSER = tkinter.Entry(root0, width=60, textvariable=USER)
entryUSER.place(x=120,y=75,width=100,height=30)

def Login(*args):
	global IP, PORT, user
	IP, PORT = entryIP.get().split(':')
	user = entryUSER.get()
	if not user:
		tkinter.messagebox.showwarning('warning', message='用戶(hù)名為空!')
	else:
		root0.destroy()

loginButton = tkinter.Button(root0, text ="登錄", command = Login,bg="Yellow")
loginButton.place(x=135,y=110,width=40,height=25)
root0.bind('<Return>', Login)

root0.mainloop()

# 建立連接
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((IP, int(PORT)))
if user:
  s.send(user.encode()) # 發(fā)送用戶(hù)名
else:
  s.send('用戶(hù)名不存在'.encode())
  user = IP + ':' + PORT

# 聊天窗口
root1 = tkinter.Tk()
root1.geometry("640x480")
root1.title('群聊')
root1.resizable(0,0)

# 消息界面
listbox = ScrolledText(root1)
listbox.place(x=5, y=0, width=640, height=320)
listbox.tag_config('tag1', foreground='red',backgroun="yellow")
listbox.insert(tkinter.END, '歡迎進(jìn)入群聊,大家開(kāi)始聊天吧!', 'tag1')

INPUT = tkinter.StringVar()
INPUT.set('')
entryIuput = tkinter.Entry(root1, width=120, textvariable=INPUT)
entryIuput.place(x=5,y=320,width=580,height=170)

# 在線用戶(hù)列表
listbox1 = tkinter.Listbox(root1)
listbox1.place(x=510, y=0, width=130, height=320)


def send(*args):
	message = entryIuput.get() + '~' + user + '~' + chat
	s.send(message.encode())
	INPUT.set('')

sendButton = tkinter.Button(root1, text ="\n發(fā)\n\n\n送",anchor = 'n',command = send,font=('Helvetica', 18),bg = 'white')
sendButton.place(x=585,y=320,width=55,height=300)
root1.bind('<Return>', send)


def receive():
	global uses
	while True:
		data = s.recv(1024)
		data = data.decode()
		print(data)
		try:
			uses = json.loads(data)
			listbox1.delete(0, tkinter.END)
			listbox1.insert(tkinter.END, "當(dāng)前在線用戶(hù)")
			listbox1.insert(tkinter.END, "------Group chat-------")
			for x in range(len(uses)):
				listbox1.insert(tkinter.END, uses[x])
			users.append('------Group chat-------')
		except:
			data = data.split('~')
			message = data[0]
			userName = data[1]
			chatwith = data[2]
			message = '\n' + message
			if chatwith == '------Group chat-------':  # 群聊
				if userName == user:
					listbox.insert(tkinter.END, message)
				else:
					listbox.insert(tkinter.END, message)
			elif userName == user or chatwith == user: # 私聊
				if userName == user:
					listbox.tag_config('tag2', foreground='red')
					listbox.insert(tkinter.END, message, 'tag2')
				else:
					listbox.tag_config('tag3', foreground='green')
					listbox.insert(tkinter.END, message,'tag3')

			listbox.see(tkinter.END)
r = threading.Thread(target=receive)
r.start() # 開(kāi)始線程接收信息

root1.mainloop()
s.close()

到此這篇關(guān)于Python實(shí)現(xiàn)網(wǎng)絡(luò)聊天室的示例代碼(支持多人聊天與私聊)的文章就介紹到這了,更多相關(guān)Python 網(wǎng)絡(luò)聊天室內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 使用pyecharts生成Echarts網(wǎng)頁(yè)的實(shí)例

    使用pyecharts生成Echarts網(wǎng)頁(yè)的實(shí)例

    今天小編就為大家分享一篇使用pyecharts生成Echarts網(wǎng)頁(yè)的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08
  • Python運(yùn)算符的應(yīng)用超全面詳細(xì)教程

    Python運(yùn)算符的應(yīng)用超全面詳細(xì)教程

    Python運(yùn)算符是為了實(shí)現(xiàn)數(shù)值或字符運(yùn)算的特殊符號(hào)。Python運(yùn)算符可以分為算術(shù)運(yùn)算符、邏輯運(yùn)算符、賦值運(yùn)算符、成員運(yùn)算符、身份運(yùn)算符、比較運(yùn)算符、三目運(yùn)算符等。接下來(lái),我們就開(kāi)始來(lái)學(xué)習(xí)這一堆符號(hào)吧
    2022-07-07
  • 在Windows服務(wù)器下用Apache和mod_wsgi配置Python應(yīng)用的教程

    在Windows服務(wù)器下用Apache和mod_wsgi配置Python應(yīng)用的教程

    這篇文章主要介紹了在Windows服務(wù)器下用Apache和mod_wsgi配置Python應(yīng)用的教程,本文選擇以flask框架作為示例,需要的朋友可以參考下
    2015-05-05
  • 在SAE上部署Python的Django框架的一些問(wèn)題匯總

    在SAE上部署Python的Django框架的一些問(wèn)題匯總

    這篇文章主要介紹了在SAE上部署Python的Django框架的一些問(wèn)題匯總,SAE是新浪的一個(gè)在線APP部署平臺(tái),并且對(duì)Python應(yīng)用提供相關(guān)支持,需要的朋友可以參考下
    2015-05-05
  • SecureCRTSecure7.0查看連接密碼的步驟

    SecureCRTSecure7.0查看連接密碼的步驟

    SecureCRTSecure7密碼查看的方法大概可以分為兩個(gè)步驟,第一步需要查看系統(tǒng)保存的連接的ini文件,第二步破解加密之后的密碼,具體腳本請(qǐng)參考下本文
    2021-06-06
  • Pycharm如何運(yùn)行.py文件的方法步驟

    Pycharm如何運(yùn)行.py文件的方法步驟

    這篇文章主要介紹了Pycharm如何運(yùn)行.py文件的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • Python中常用的統(tǒng)計(jì)檢驗(yàn)代碼分享

    Python中常用的統(tǒng)計(jì)檢驗(yàn)代碼分享

    統(tǒng)計(jì)檢驗(yàn)是數(shù)據(jù)分析中的重要工具,用于檢驗(yàn)數(shù)據(jù)集中的差異、關(guān)聯(lián)和分布等統(tǒng)計(jì)性質(zhì),本文為大家整理了常見(jiàn)的統(tǒng)計(jì)檢驗(yàn)方法,希望對(duì)大家有所幫助
    2024-01-01
  • 詳解Python編程中time模塊的使用

    詳解Python編程中time模塊的使用

    這篇文章主要介紹了詳解Python編程中time模塊的使用,是Python入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-11-11
  • python 解壓pkl文件的方法

    python 解壓pkl文件的方法

    今天小編就為大家分享一篇python 解壓pkl文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-10-10
  • Tensorflow與RNN、雙向LSTM等的踩坑記錄及解決

    Tensorflow與RNN、雙向LSTM等的踩坑記錄及解決

    這篇文章主要介紹了Tensorflow與RNN、雙向LSTM等的踩坑記錄及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05

最新評(píng)論