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发送邮件附件以定时备份MySQL的教程
Apr 25 Python
Python中encode()方法的使用简介
May 18 Python
python实现简单ftp客户端的方法
Jun 28 Python
分析Python读取文件时的路径问题
Feb 11 Python
pandas删除行删除列增加行增加列的实现
Jul 06 Python
python使用多线程编写tcp客户端程序
Sep 02 Python
Pycharm最新激活码2019(推荐)
Dec 31 Python
PyTorch学习:动态图和静态图的例子
Jan 06 Python
浅谈python元素如何去重,去重后如何保持原来元素的顺序不变
Feb 28 Python
Python基于pandas绘制散点图矩阵代码实例
Jun 04 Python
Python基于gevent实现文件字符串查找器
Aug 11 Python
pytorch 实现在测试的时候启用dropout
May 27 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+mysql留言本源码
2009/11/11 PHP
PHP MYSQL乱码问题,使用SET NAMES utf8校正
2009/11/30 PHP
php中print(),print_r(),echo()的区别详解
2014/12/01 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
2015/05/12 PHP
Zend Framework教程之Zend_Helpers动作助手ViewRenderer用法详解
2016/07/20 PHP
PHP编程实现脚本异步执行的方法
2017/08/09 PHP
发现的以前不知道的函数
2006/09/19 Javascript
javascript将数组插入到另一个数组中的代码
2013/01/10 Javascript
常见浏览器多长时间会提示“脚本运行时间过长”总结
2014/04/29 Javascript
JavaScript 实现打印,打印预览,打印设置
2014/12/30 Javascript
jQuery通用的全局遍历方法$.each()用法实例
2016/07/04 Javascript
js日期相关函数dateAdd,dateDiff,dateFormat等介绍
2016/09/24 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
2017/01/13 Javascript
浅析Vue.js中v-bind v-model的使用和区别
2018/12/04 Javascript
前端路由&webpack基础配置详解
2019/06/10 Javascript
element-ui 文件上传修改文件名的方法示例
2019/11/05 Javascript
javascript实现简单留言板案例
2021/02/09 Javascript
[25:45]2018DOTA2亚洲邀请赛4.5SOLO赛 Sylar vs Paparazi
2018/04/06 DOTA
Python函数式编程指南(二):从函数开始
2015/06/24 Python
Python的SQLalchemy模块连接与操作MySQL的基础示例
2016/07/11 Python
Python控制多进程与多线程并发数总结
2016/10/26 Python
django中ORM模型常用的字段的使用方法
2019/03/05 Python
Python正则表达式匹配和提取IP地址
2019/06/06 Python
详解Python对JSON中的特殊类型进行Encoder
2019/07/15 Python
Django框架 querySet功能解析
2019/09/04 Python
Python实现数值积分方式
2019/11/20 Python
Python 炫技操作之合并字典的七种方法
2020/04/10 Python
python中matplotlib实现随鼠标滑动自动标注代码
2020/04/23 Python
美国儿童玩具、装扮和玩偶商店:Magic Cabin
2018/09/02 全球购物
用C#语言写出与SQLSERVER访问时的具体过程
2013/04/16 面试题
会计与审计专业大专生求职信
2013/10/03 职场文书
促销活动策划方案
2014/01/12 职场文书
2015年大学团支部工作总结
2015/05/13 职场文书
小学感恩主题班会
2015/08/12 职场文书
英语版自我评价,35句话轻松搞定
2019/10/08 职场文书
Java虚拟机内存结构及编码实战分享
2022/04/07 Java/Android