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 相关文章推荐
python实现根据图标提取分类应用程序实例
Sep 28 Python
Python中集合的内建函数和内建方法学习教程
Aug 19 Python
python 打印直角三角形,等边三角形,菱形,正方形的代码
Nov 21 Python
Python实现批量读取图片并存入mongodb数据库的方法示例
Apr 02 Python
Python 控制终端输出文字的实例
Jul 12 Python
python获取网络图片方法及整理过程详解
Dec 20 Python
pytorch 图像预处理之减去均值,除以方差的实例
Jan 02 Python
keras训练曲线,混淆矩阵,CNN层输出可视化实例
Jun 15 Python
django 将自带的数据库sqlite3改成mysql实例
Jul 09 Python
python在linux环境下安装skimage的示例代码
Oct 14 Python
python利用opencv保存、播放视频
Nov 02 Python
Windows安装Anaconda3的方法及使用过程详解
Jun 11 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
调频问题解答
2021/03/01 无线电
php模拟socket一次连接,多次发送数据的实现代码
2011/07/26 PHP
解析curl提交GET,POST,Cookie的简单方法
2013/06/29 PHP
php+mysql结合Ajax实现点赞功能完整实例
2015/01/30 PHP
php+ajax无刷新上传图片实例代码
2015/11/17 PHP
PHP上传文件参考配置大文件上传
2015/12/16 PHP
javascript里的条件判断
2007/02/27 Javascript
Wordpress ThickBox 添加“查看原图”效果代码
2010/12/11 Javascript
html+js实现动态显示本地时间
2013/09/21 Javascript
简易的投票系统以及js刷票思路和方法
2015/04/07 Javascript
javascript日期计算实例分析
2015/06/29 Javascript
jQuery表单验证功能实例
2015/08/28 Javascript
JQuery通过AJAX从后台获取信息显示在表格上并支持行选中
2015/09/15 Javascript
JS基于VML技术实现的五角星礼花效果代码
2015/10/26 Javascript
为何JS操作的href都是javascript:void(0);呢
2015/11/12 Javascript
简单实现轮播图效果的实例
2016/07/15 Javascript
基于Vuejs框架实现翻页组件
2020/06/29 Javascript
微信小程序-拍照或选择图片并上传文件
2017/01/06 Javascript
在Vue项目中引入JQuery-ui插件的讲解
2019/01/27 jQuery
vue-cli 3 全局过滤器的实例代码详解
2019/06/03 Javascript
jquery.pager.js实现分页效果
2019/07/29 jQuery
python实现class对象转换成json/字典的方法
2016/03/11 Python
Python中断言Assertion的一些改进方案
2016/10/27 Python
python,Django实现的淘宝客登录功能示例
2019/06/12 Python
解决TensorFlow程序无限制占用GPU的方法
2020/06/30 Python
国际书籍零售商:Wordery
2017/11/01 全球购物
什么是用户模式(User Mode)与内核模式(Kernel Mode) ?
2014/07/21 面试题
销售自荐信
2013/10/22 职场文书
农民入党思想汇报
2014/01/03 职场文书
电气工程及其自动化专业求职信
2014/06/23 职场文书
小学雷锋月活动总结
2014/07/03 职场文书
庆元旦活动总结
2014/07/09 职场文书
教师思想作风整顿个人剖析材料
2014/10/10 职场文书
雷锋之歌观后感
2015/06/10 职场文书
vue3中的组件间通信
2021/03/31 Vue.js
HTML5 新增内容和 API详解
2021/11/17 HTML / CSS