Python基于Socket实现简易多人聊天室的示例代码


Posted in Python onNovember 29, 2020

前言

套接字(Sockets)是双向通信信道的端点。 套接字可以在一个进程内,在同一机器上的进程之间,或者在不同主机的进程之间进行通信,主机可以是任何一台有连接互联网的机器。

套接字可以通过多种不同的通道类型实现:Unix域套接字,TCP,UDP等。 套接字库提供了处理公共传输的特定类,以及一个用于处理其余部分的通用接口。

socket模块:

要创建套接字,必须使用套接字模块中的socket.socket()函数,该函数具有一般语法

s = socket.socket (socket_family, socket_type, protocol = 0)

参数 描述
socket_family 它的值可以是:AF_UNIX或AF_INET,如前所述。
socket_type 它的值可以是:SOCK_STREAM或SOCK_DGRAM。
protocol 这通常被省略,默认为0。

常用方法:

序号 方法 描述
1 s.bind() 此方法将地址(主机名,端口号对)绑定到套接字。
2 s.recvfrom() 此方法接收UDP消息,返回值是一对(字节, 地址) ,其中字节是代表接收到的数据的字节对象,而地址是发送数据的套接字的地址
3 s.sendto() 此方法发送UDP消息,将数据发送到套接字。该套接字不应连接到远程套接字,因为目标套接字是由address指定的
4 s.close() 此方法关闭套接字,套接字对象上所有以后的操作都将失败。远端将不再接收任何数据(在清除排队的数据之后)。套接字在被垃圾回收时会自动关闭
5 socket.gethostname() 返回主机名,返回一个字符串,其中包含当前正在执行Python解释器的计算机的主机名。

示例1

服务器端

#sever.py
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
host = socket.gethostname()
port = 8088
s.bind((host,port))
try:
  while True:
    receive_data,addr = s.recvfrom(1024)
    print("来自服务器" + str(addr) + "的消息:")
    print(receive_data.decode('utf-8'))
    msg = input('please input send to msg:')
    s.sendto(msg.encode('utf-8'),addr)
except:
  s.close()

客户端

#client.py
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
try:
  while True:
    host = socket.gethostname()
    port = 8088
    send_data = input('please input msg:')
    s.sendto(send_data.encode('utf-8'),(host,port))
    msg,addr = s.recvfrom(1024)
    print("来自服务器" + str(addr) + "的消息:")
    print(msg.decode('utf-8'))
except:
  s.close()

服务端示例

Python基于Socket实现简易多人聊天室的示例代码

客户端示例

Python基于Socket实现简易多人聊天室的示例代码

简易的UDP聊天实现了,下面我们来优化一下示例。

示例2

服务端:

#server.py
import socket
import logging

def main():
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建socket对象

  addr = ('127.0.0.1', 9999)
  s.bind(addr) # 绑定地址和端口

  logging.info('UDP Server on %s:%s...', addr[0], addr[1])

  user = {} # 存放字典{addr:name}
  while True:
    try:
      data, addr = s.recvfrom(1024) # 等待接收客户端消息存放在2个变量data和addr里
      if not addr in user: # 如果addr不在user字典里则执行以下代码
        for address in user: # 从user遍历数据出来address
          s.sendto(data + ' 进入聊天室...'.encode('utf-8'), address) # 发送user字典的data和address到客户端
        user[addr] = data.decode('utf-8') # 接收的消息解码成utf-8并存在字典user里,键名定义为addr
        continue # 如果addr在user字典里,跳过本次循环

      if 'EXIT'.lower() in data.decode('utf-8'):#如果EXIT在发送的data里
        name = user[addr]  #user字典addr键对应的值赋值给变量name
        user.pop(addr)   #删除user里的addr
        for address in user:  #从user取出address
          s.sendto((name + ' 离开了聊天室...').encode(), address)   #发送name和address到客户端
      else:  
        print('"%s" from %s:%s' %(data.decode('utf-8'), addr[0], addr[1])) 
        for address in user:  #从user遍历出address
          if address != addr: #address不等于addr时间执行下面的代码
            s.sendto(data, address)   #发送data和address到客户端

    except ConnectionResetError:
      logging.warning('Someone left unexcept.')

if __name__ == '__main__':
  main()

客户端:

#clinet.py
import socket
import threading

def recv(sock, addr):
  '''
  一个UDP连接在接收消息前必须要让系统知道所占端口
  也就是需要send一次,否则win下会报错
  '''
  sock.sendto(name.encode('utf-8'), addr)
  while True:
    data = sock.recv(1024)
    print(data.decode('utf-8'))


def send(sock, addr):
  '''
    发送数据的方法
    参数:
      sock:定义一个实例化socket对象
      server:传递的服务器IP和端口
  '''
  while True:
    string = input('')
    message = name + ' : ' + string
    data = message.encode('utf-8')
    sock.sendto(data, addr)
    if string.lower() == 'EXIT'.lower():
      break

def main():
  '''
    主函数执行方法,通过多线程来实现多个客户端之间的通信
  '''
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  server = ('127.0.0.1', 9999)
  tr = threading.Thread(target=recv, args=(s, server), daemon=True)
  ts = threading.Thread(target=send, args=(s, server))
  tr.start()
  ts.start()
  ts.join()
  s.close()

if __name__ == '__main__':
  print("-----欢迎来到聊天室,退出聊天室请输入'EXIT(不分大小写)'-----")
  name = input('请输入你的名称:')
  print('-----------------%s------------------' % name)
  main()

支持多人的简易聊天室示例,多个客户端通过一个服务器进行之间通信

Python基于Socket实现简易多人聊天室的示例代码 

Python基于Socket实现简易多人聊天室的示例代码 

Python基于Socket实现简易多人聊天室的示例代码 

Python基于Socket实现简易多人聊天室的示例代码

到此这篇关于Python基于Socket实现简易多人聊天室的示例代码的文章就介绍到这了,更多相关Python Socket多人聊天室内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python3实现UDP协议的服务器和客户端
Jun 14 Python
Python中xrange与yield的用法实例分析
Dec 26 Python
python构建深度神经网络(续)
Mar 10 Python
解决安装tensorflow遇到无法卸载numpy 1.8.0rc1的问题
Jun 13 Python
python获取命令行输入参数列表的实例代码
Jun 23 Python
Python3实现获取图片文字里中文的方法分析
Dec 13 Python
python实现将多个文件分配到多个文件夹的方法
Jan 07 Python
对Python Class之间函数的调用关系详解
Jan 23 Python
Python3 io文本及原始流I/O工具用法详解
Mar 23 Python
python获取系统内存占用信息的实例方法
Jul 17 Python
Python机器学习之基于Pytorch实现猫狗分类
Jun 08 Python
python Django框架快速入门教程(后台管理)
Jul 21 Python
python3实现飞机大战
Nov 29 #Python
python之pygame模块实现飞机大战完整代码
Nov 29 #Python
Python使用Pygame绘制时钟
Nov 29 #Python
详解pandas赋值失败问题解决
Nov 29 #Python
python 获取剪切板内容的两种方法
Nov 28 #Python
快速创建python 虚拟环境
Nov 28 #Python
Python基于Webhook实现github自动化部署
Nov 28 #Python
You might like
php正则
2006/07/07 PHP
Zend 输出产生XML解析错误
2009/03/03 PHP
php修改时间格式的代码
2011/05/29 PHP
PHP会员找回密码功能的简单实现
2016/09/05 PHP
用js实现控制内容的向上向下滚动效果
2007/06/26 Javascript
JavaScript性能陷阱小结(附实例说明)
2010/12/28 Javascript
Javascript通过overflow控制列表闭合与展开的方法
2015/05/15 Javascript
js实现a标签超链接提交form表单的方法
2015/06/24 Javascript
jQuery EasyUI框架中的Datagrid数据表格组件结构详解
2016/06/09 Javascript
浅谈jQuery为哪般去掉了浏览器检测
2016/08/29 Javascript
Angularjs 实现一个幻灯片示例代码
2016/09/08 Javascript
微信小程序左右滑动切换页面详解及实例代码
2017/02/28 Javascript
vue.js实现数据动态响应 Vue.set的简单应用
2017/06/15 Javascript
微信小程序如何再次获取用户授权的方法
2019/05/10 Javascript
jQuery实现视频展示效果
2020/05/30 jQuery
基于vue--key值的特殊用处详解
2020/07/31 Javascript
Openlayers3实现车辆轨迹回放功能
2020/09/29 Javascript
[01:02:47]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
Python探索之修改Python搜索路径
2017/10/25 Python
numpy.delete删除一列或多列的方法
2018/04/03 Python
在scrapy中使用phantomJS实现异步爬取的方法
2018/12/17 Python
自学python的建议和周期预算
2019/01/30 Python
Django多进程滚动日志问题解决方案
2019/12/17 Python
html5 canvas绘制矩形和圆形的实例代码
2016/06/16 HTML / CSS
美国知名艺术画网站:Art.com
2017/02/09 全球购物
用缩写的指针比较"if(p)" 检查空指针是否可靠?如果空指针的内部表达不是0会怎么样?
2014/01/05 面试题
优秀学生干部个人的自我评价
2013/10/04 职场文书
《泉水》教学反思
2014/04/11 职场文书
中文专业求职信
2014/06/20 职场文书
上课随便讲话检讨书
2014/09/12 职场文书
2014年档案管理工作总结
2014/11/17 职场文书
委托证明范本
2014/11/25 职场文书
办公室年度工作总结2015
2015/05/21 职场文书
Mysql案例刨析事务隔离级别
2021/09/25 MySQL
微软Win11有哪些隐藏功能? windows11多个功能汇总
2021/11/21 数码科技