利用socket套接字实现多台计算机之间的连接

server:

import socket                                               #socket 是一种套接字,用来描述IP和port
import os
import threading                                            #多线程
import queue
import sys
import timehost="127.0.0.1"                                   #server's IP
port=6000                                                   #server's portclass Server(threading.Thread):def __init__(self):self.messages = queue.Queue()self.lock = threading.Lock()self.users=[]                           #记录当前在线的用户threading.Thread.__init__(self)self.tcpsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #实例化一个socket,用于Internet进程间通信,使用TCP协议os.chdir(sys.path[0])#事件处理函数def handle(self,conn,addr):try:while True:data=conn.recv(1024).decode()if data=="register":self.register(conn,addr)elif data=="submit":username=self.submit(conn,addr)elif data=="send":self.send(conn,addr,username)conn.close()except:self.users.remove(conn)conn.close()#处理账号登录def submit(self,conn,addr):conn.send("y".encode())                #第二次握手username=conn.recv(1024).decode()password=conn.recv(1024).decode()filenames=os.listdir(r"user")calculator=0for i in filenames:if (username+".txt")==i:with open(f"user/{username}.txt", "r") as file:data = file.read()if password==data:self.users.append(conn)conn.send("y".encode())else:conn.send("n".encode())breakelse:calculator+=1continueif calculator==len(filenames):conn.send("n".encode())return username#处理账号注册def register(self,conn,addr):conn.send("y".encode())                #第二次握手username=conn.recv(1024).decode()password=conn.recv(1024).decode()filenames=os.listdir(r"user")calculator=0for i in filenames:if (username+".txt")==i:conn.send("n".encode())breakelse:calculator+=1continueif calculator==len(filenames):with open(f"user/{username}.txt","w") as file:file.write(password)conn.send("y".encode())#处理发送消息def send(self,conn,addr,username):mes=conn.recv(1024).decode()m=username+": "+mesself.Load(m)# 将地址与数据(需发送给客户端)存入messages队列def Load(self, data):self.lock.acquire()try:self.messages.put(data)finally:self.lock.release()#将messages中的消息发送给所有登录的用户def sendData(self):while True:if not self.messages.empty():message = self.messages.get()print(message)for i in self.users:i.send(message.encode())def run(self):self.tcpsocket.bind((host,port))          #将host和port(元组)绑定在tcpsocket套接字上self.tcpsocket.listen(5)                  #开始TCP监听,传入参数为可以同时挂起的最大数量print("server is waiting for client's linking...")q = threading.Thread(target=self.sendData)q.start()while True:conn, addr = self.tcpsocket.accept()       #新建一个套接字print("连接成功")t = threading.Thread(target=self.handle, args=(conn, addr))t.start()self.tcpsocket.close()if __name__ == '__main__':server = Server()server.start()
a=socket.gethostname()

client:

import socket
import wx
import time
import threadinghost="121.62.17.41"     #  填服务器的ip
port=61167              #  填服务器的端口,这里我用了内网穿透所以不是6000class MyFrame(wx.Frame):   def __init__(self,parent,id):wx.Frame.__init__(self,parent,id,title="网络聊天室",pos=(400,200),size=(400,300))panel=wx.Panel(parent=self)                               #创建画板self.title=wx.StaticText(panel,label="请输入用户名和密码")    #创建标题#创建确定和取消按钮并绑定事件self.bt_confirm=wx.Button(panel,label="确定")self.bt_confirm.Bind(wx.EVT_BUTTON,self.OnclickSubmit)self.bt_cancel=wx.Button(panel,label="清空")self.bt_cancel.Bind(wx.EVT_BUTTON,self.OnclickCancel)self.bt_register=wx.Button(panel,label="注册")self.bt_register.Bind(wx.EVT_BUTTON,self.OnclickRegister)self.label_user=wx.StaticText(panel,label="用户名:")self.text_user=wx.TextCtrl(panel,style=wx.TE_LEFT)self.label_pwd=wx.StaticText(panel,label="密   码:")self.text_password=wx.TextCtrl(panel,style=wx.TE_PASSWORD)#添加容器,容器中控件横向排列hsizer_user=wx.BoxSizer(wx.HORIZONTAL)hsizer_user.Add(self.label_user,proportion=0,flag=wx.ALL,border=5)hsizer_user.Add(self.text_user,proportion=1,flag=wx.ALL,border=5)hsizer_pwd=wx.BoxSizer(wx.HORIZONTAL)hsizer_pwd.Add(self.label_pwd,proportion=0,flag=wx.ALL,border=5)hsizer_pwd.Add(self.text_password,proportion=1,flag=wx.ALL,border=5)hsizer_button=wx.BoxSizer(wx.HORIZONTAL)hsizer_button.Add(self.bt_confirm,proportion=0,flag=wx.ALIGN_CENTER,border=5)hsizer_button.Add(self.bt_cancel,proportion=0,flag=wx.ALIGN_CENTER,border=5)hsizer_button.Add(self.bt_register,proportion=0,flag=wx.ALIGN_CENTER,border=5)#添加容器,容器中控件纵向排列vsizer_all=wx.BoxSizer(wx.VERTICAL)vsizer_all.Add(self.title,proportion=0,flag=wx.BOTTOM|wx.TOP|wx.ALIGN_CENTER,border=15)vsizer_all.Add(hsizer_user,proportion=0,flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=45)vsizer_all.Add(hsizer_pwd,proportion=0,flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=45)vsizer_all.Add(hsizer_button,proportion=0,flag=wx.ALIGN_CENTER|wx.TOP,border=15)panel.SetSizer(vsizer_all)def OnclickSubmit(self,event):message=""username=self.text_user.GetValue()password=self.text_password.GetValue()if username=="" or password=="":message="用户名和密码不能为空"wx.MessageBox(message)elif len(username)>=20 or len(password)>=20:message="用户名和密码不匹配或用户名不存在"wx.MessageBox(message)else:send_data="submit"clientsocket.send(send_data.encode())clientsocket.recv(1024)                                #第二次握手clientsocket.send(username.encode())clientsocket.send(password.encode())recvdata=clientsocket.recv(1024).decode()if recvdata=="n":message="用户名和密码不匹配或用户名不存在"wx.MessageBox(message)elif recvdata=="y":message="登录成功"wx.MessageBox(message)self.Onclose()                         mainframe=MainFrame(parent=None,id=-1)   mainframe.Show()r = threading.Thread(target=mainframe.receive)r.start()  # 开始线程接收信息                         return Truedef OnclickCancel(self,event):self.text_user.SetValue("")               #清空输入的用户名self.text_password.SetValue("")           #清空输入的密码def OnclickRegister(self,event):self.Onclose()                       registerframe=RegisterFrame(parent=None,id=-1)   registerframe.Show()                        return Truedef Onclose(self):self.Destroy()class MainFrame(wx.Frame):def __init__(self,parent,id):wx.Frame.__init__(self,parent,id,title="网络聊天室",pos=(400,200),size=(800,500))panel=wx.Panel(parent=self)                                 #创建画板self.title=wx.StaticText(panel,label="欢迎来到网络聊天室")    #创建标题#创建发送按钮self.bt_send=wx.Button(panel,label="发送")self.bt_send.Bind(wx.EVT_BUTTON,self.OnclickSend)#页面元素self.text_send=wx.TextCtrl(panel,style=wx.TE_LEFT)self.text=wx.TextCtrl(panel,style=wx.TE_MULTILINE|wx.TE_READONLY)self.text.AppendText("加入聊天室\n")##添加容器,容器中控件横向排列hsizer_send=wx.BoxSizer(wx.HORIZONTAL)hsizer_send.Add(self.text_send,proportion=1,flag=wx.ALL,border=5)hsizer_send.Add(self.bt_send,proportion=0,flag=wx.ALL,border=5)#添加容器,容器中控件纵向排列vsizer_all=wx.BoxSizer(wx.VERTICAL)vsizer_all.Add(self.title,proportion=0,flag=wx.BOTTOM|wx.TOP|wx.ALIGN_CENTER,border=15)vsizer_all.Add(self.text,proportion=5,flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=45)vsizer_all.Add(hsizer_send,proportion=1,flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=40)panel.SetSizer(vsizer_all)def OnclickSend(self,event):message=self.text_send.GetValue()self.text_send.Clear()if message=="":passelse:send_data="send"clientsocket.send(send_data.encode())time.sleep(0.5)                                  #还没解决三次握手的问题clientsocket.send(message.encode())def receive(self):try:while True:recvdata=clientsocket.recv(1024).decode()self.text.AppendText(recvdata+"\n")except:pass                                #静默退出class RegisterFrame(wx.Frame):def __init__(self,parent,id):wx.Frame.__init__(self,parent,id,title="网络聊天室",pos=(400,200),size=(400,300))panel=wx.Panel(parent=self)                               #创建画板self.title=wx.StaticText(panel,label="注册账号")    #创建标题#创建确定和取消按钮并绑定事件self.bt_confirm=wx.Button(panel,label="确定")self.bt_confirm.Bind(wx.EVT_BUTTON,self.OnclickSubmit)self.bt_cancel=wx.Button(panel,label="取消")self.bt_cancel.Bind(wx.EVT_BUTTON,self.OnclickCancel)self.label_user=wx.StaticText(panel,label="用户名:")self.text_user=wx.TextCtrl(panel,style=wx.TE_LEFT)self.label_pwd=wx.StaticText(panel,label="密   码:")self.text_password=wx.TextCtrl(panel,style=wx.TE_PASSWORD)#添加容器,容器中控件横向排列hsizer_user=wx.BoxSizer(wx.HORIZONTAL)hsizer_user.Add(self.label_user,proportion=0,flag=wx.ALL,border=5)hsizer_user.Add(self.text_user,proportion=1,flag=wx.ALL,border=5)hsizer_pwd=wx.BoxSizer(wx.HORIZONTAL)hsizer_pwd.Add(self.label_pwd,proportion=0,flag=wx.ALL,border=5)hsizer_pwd.Add(self.text_password,proportion=1,flag=wx.ALL,border=5)hsizer_button=wx.BoxSizer(wx.HORIZONTAL)hsizer_button.Add(self.bt_confirm,proportion=0,flag=wx.ALIGN_CENTER,border=5)hsizer_button.Add(self.bt_cancel,proportion=0,flag=wx.ALIGN_CENTER,border=5)#添加容器,容器中控件纵向排列vsizer_all=wx.BoxSizer(wx.VERTICAL)vsizer_all.Add(self.title,proportion=0,flag=wx.BOTTOM|wx.TOP|wx.ALIGN_CENTER,border=15)vsizer_all.Add(hsizer_user,proportion=0,flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=45)vsizer_all.Add(hsizer_pwd,proportion=0,flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=45)vsizer_all.Add(hsizer_button,proportion=0,flag=wx.ALIGN_CENTER|wx.TOP,border=15)panel.SetSizer(vsizer_all)def OnclickSubmit(self,event):message=""username=self.text_user.GetValue()password=self.text_password.GetValue()if username=="" or password=="":message="用户名和密码不能为空"wx.MessageBox(message)elif len(username)>=20 or len(password)>=20:message="用户名或密码太长"wx.MessageBox(message)else:send_data="register"clientsocket.send(send_data.encode())clientsocket.recv(1024)                               #第二次握手clientsocket.send(username.encode())clientsocket.send(password.encode())recvdata=clientsocket.recv(1024).decode()if recvdata=="n":message="用户名已存在"wx.MessageBox(message)elif recvdata=="y":message="注册成功"wx.MessageBox(message)self.Onclose()                         frame=MyFrame(parent=None,id=-1)   frame.Show()                         return Truedef OnclickCancel(self,event):self.Onclose()                         frame=MyFrame(parent=None,id=-1)   frame.Show()                         return Truedef Onclose(self):self.Destroy()class App(wx.App):def OnInit(self):frame=MyFrame(parent=None,id=-1)frame.Show()return Trueif __name__=="__main__":clientsocket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)                                                 clientsocket.connect((host,port))
#GUIapp=App()app.MainLoop()clientsocket.close()

【python】实现多人网络聊天室相关推荐

  1. 视频教程-多人网络聊天室-Unity3D

    多人网络聊天室 广州市码锋网络有限责任公司创始人,从事游戏开发九年,熟练前后端的各种技术,我很乐意将企业中商用的技术分享给你,帮助你解决工作的各种问题. 官剑铭 ¥39.00 立即订阅 扫码下载「CS ...

  2. Linux C多人网络聊天室

    经过好几天的日夜奋斗,总算把这个聊天室给做出来了,虽然说不上多好,但也是这几天从早到晚劳动的成功,所以就写这篇博文来记录一下啦.别的不敢说,确保能用就是了,完整代码在最后哦~ 当然啦,如果有幸被转发, ...

  3. python基于udp的网络聊天室再用tkinter显示_Python实现网络聊天室的示例代码(支持多人聊天与私聊)...

    实验名称: 网络聊天室 功能: i. 掌握利用Socket进行编程的技术 ii. 掌握多线程技术,保证双方可以同时发送 iii. 建立聊天工具 iv. 可以和单人聊天 v. 可以和多个人同时进行聊天 ...

  4. Java NIO示例:多人网络聊天室完整代码

    服务端:  package cn.zhangxueliang.herostory.chatroom;import java.io.IOException; import java.net.InetSo ...

  5. Java NIO示例:多人网络聊天室

    一个多客户端聊天室,支持多客户端聊天,有如下功能: 功能1: 客户端通过Java NIO连接到服务端,支持多客户端的连接 功能2:客户端初次连接时,服务端提示输入昵称,如果昵称已经有人使用,提示重新输 ...

  6. python socket + tkinter实现网络聊天室

    个人博客文章链接:http://www.huqj.top/article?id=169 最近突然想用socket做个聊天室程序,之前用java写过一个文件传输的程序,这次就用python做一下,顺便也 ...

  7. JAVA 基于TCP的多人网络聊天室 实现过程

    主要实现功能 多人在线聊天 发送私密消息 新用户加入提示 用户离开提示 功能演示 服务器: package dome;import java.io.DataInputStream; import ja ...

  8. [NUAA]Python用UDP协议建立带有私聊功能的网络聊天室-建立聊天工具

    文章目录 前言 1.网络聊天室的基本架构是什么? 1.1 客户端和服务器的架构 1.2 通信协议的选择以及多线程通信 1.2.1 多线程通信 1.2.2 通信协议选择 1.3 前后端功能设计思路 1. ...

  9. Python实现网络聊天室(支持多人聊天与私聊)

    实验名称: 网络聊天室 功能: i. 掌握利用Socket进行编程的技术 ii. 掌握多线程技术,保证双方可以同时发送 iii. 建立聊天工具 iv. 可以和单人聊天 v. 可以和多个人同时进行聊天 ...

最新文章

  1. IntelliJ IDEA中用快捷键自动创建测试类
  2. python和R数据类型查看、赋值、列表、for循环、函数用法对比示例
  3. 解决办法:CMake编译时出现“error in configuration process project files may be invalid”
  4. POJ_2104 K-th Number 【主席树】
  5. plex linux 数据目录,shareplex日常维护文档
  6. Function.prototype.bind相关知识点
  7. dos怎么退出debug_电脑主板坏了怎么办?浅谈主板常见的故障以及应对办法
  8. Python之动态网页爬虫方案介绍及selenium+chrome详解
  9. 如何使用计算机计算平方面积,平方怎么算面积公式-3种方法详解须知
  10. 路由器的几种工作模式
  11. 幻想未来,助你成为人生赢家?
  12. 我在离天空最近的城市
  13. 水果店怎么开业吸引客户来,水果店新店开业如何吸引客人
  14. vue获取浏览器的指纹码
  15. Django-模型层
  16. python 判断excel单元格为空_用python检测空白Excel单元格
  17. IDEA 206个快捷键 动图演示,键盘侠标配
  18. Golang单元测试指引
  19. AI篮球裁判火了,走步算得特别准,就问哈登慌不慌
  20. [ Bootstrap ] 可视化布局

热门文章

  1. 热门开源项目:Guns-后台管理系统
  2. android女手机弹唱take a bow,黑科技!不会乐器也能钢琴弹唱,手机上就能练习,你应该知道...
  3. (重要)同网段和不同网段设备通信过程详解
  4. Revit二开-设备(消防箱)翻模
  5. 毕业设计 基于RSSI的室内wifi定位系统
  6. 如何设计一张数据库表
  7. docker-compose搭建prometheus+granafa+alertmanager+dingtalk
  8. ANSI/ESD S20.20-2021 ESD 控制程序-电气和电子零件、组件和设备的保护 - 完整英文版(28页)
  9. EMQX 入门教程——导读
  10. python书籍收集