python多人聊天室_Python基于Socket实现简易多人聊天室

前言

套接字(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

s.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()

服务端示例

客户端示例

简易的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()

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/396662.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机考研保护一志愿,考研良心大学,保护一志愿的考研名校!

大家好,我是,今天胖胖要跟大家送一些重要的干货,就是对于选学校的小伙伴来说也好,或者是即将要参加研究生复试的小伙伴们来好胖胖在这里要跟大家说一个关于考研白名单的事情,因为大家都知道考研是会分黑名单和白名单&a…

python变量输出到文件_使用函数将多个变量写入文件

首先,要获得当前正在执行的脚本名,或者更确切地说是调用函数的模块,必须从堆栈跟踪中获取它。globals()-它将在writeToValues()函数的相同上下文中执行,因此它不会从“调用者”接收globals()。要纠正这种情况,您可以使…

嵌入式linux系统移植的四大步骤_嵌入式系统移植步骤

在嵌入式系统移植中重要的一部分是操作系统的移植,与其它操作系统相比,Linux大的特点:它是一款遵循GPL的操作系统,我们可以自由地使用、修改、和扩展它。正是由于这一特色,嵌入式系统移植过程中Linux系统受到越来越多人…

sdn框架的计算机网络管理,清华SDN实践--SDN 系统架构与数据中心应用

清华大学在SDN 的系统架构以及其在数据中心网络中的应用方面展开了深入研究,主要研究成果包括:1. 以数据为中心的软件定义网络架构 SODA(Software Defined Data Centric Networking)。与 OpenFlow 相比,SODA 大大增强了数据层面的处理能力&am…

《软件工程》课之-调查问卷的心得体会

1.这次调查是艰辛的。 2.很多人都误以为我在发小广告。。 3.很多人都不认识俄罗斯方块1010这个游戏。 4.大家对于游戏的见解千奇百怪。 5.题目出的不是很完美,下次改进。。 6.简单分析下结果,男孩子都喜欢多人的游戏,女孩的喜欢的多种多样&am…

python循环语句for求和_for循环简介

## for循环简介for循环可以用来遍历某一对象(遍历:通俗点说,就是把这个循环中的第一个元素到最后一个元素依次访问一次)。for循环的基本结构如下:![](https://img.kancloud.cn/75/33/753371a9536ed9eeb159074482ec85f0_558x174.png)说明&…

华为备份历史版本_华为手机NAS备份时提示“需处于同一局域网”的解决方法

本内容来源于什么值得买APP,观点仅代表作者本人 |作者:噩梦飘雷创作立场声明:在使用华为手机向群晖NAS中备份时发现一直无法成功,经过一番研究找到了解决方案,希望能帮到大家~前言最近看了一位老哥的帖子&a…

计算机系统集成难点,企业MES实施中存在的难点及建议

MES是企业生产管理服务的核心信息化系统。实施MES是为了将现代企业生产管理思想、理念引入企业生产管理,对企业生产管理流程进行重组和优化,促进企业生产管理水平的提高。可是作用如此大的MES系统在实施过程中能一路无阻吗?MES系统的作用1.车…

【原创】自己编写的JavaGUI一键生成(hibernate/spring/mvc/maven)工具(附带视频教程源码)...

为什么80%的码农都做不了架构师?>>> 带项目源码(https://git.oschina.net/qsyan/GeneratorFx) app下载地址(附带视频教程):http://download.csdn.net/detail/juyan2008/9769406 注明:此应用采用javafx编写…

2018-2019 20165203 《信息安全系统设计基础》第一周学习总结

2018-2019-1 20165203 《信息安全系统设计基础》第一周学习总结 教材学习内容总结 编译:gcc [选项] [文件名]选项参数表 参数对应功能-E仅执行编译预处理-S将.c代码转换为汇编语言代码-c仅执行编译操作,不进行连接操作-o指定生成的输出文件-I (大写)指定…

普通计算机怎么算根号_大学专业介绍 | 计算机专业的真实就业情况

前两天给大家简单介绍了近些年比较火的计算机类相关专业具体都有哪些不同,以及就业时的行业或者岗位的侧重点。今天呢我们继续这个话题,来聊一聊整个计算机相关专业在学习和就业过程中大概是什么样子的,希望能够给大家提供一些实实在在的参考…

设计模式总结篇系列:工厂方法模式(Factory Method)

工厂方法模式适合于对实现了同一接口或继承了同一父类的一些类进行实例的创建。一般是通过定义一个工厂类,并在其方法中实现对具有上述特点的类对象的创建。 根据具体产生类对象的方法定义形式,又可以将其分为普通工厂方法模式、多个工厂方法模式和静态工…

高新园区到大连计算机学校,大连高新区中心小学

大连市高新区中心小学简介:大连市高新区中心小学始建于2009年9月,是大连高新技术产业园区筹建的第一所直属公办学校。学校现拥有2000多名学生,87名教职员工。学校确定了“办诗韵教育,让每个孩子都幸福的教育理念”,通过…

java基础之匿名内部类

内部类:   概述: 类里边还有一个类, 里边那个类叫内部类, 外边那个类叫外部类.   分类:  成员内部类: 定义在成员位置的内部类.  局部内部类: 定义在局部位置的内部类. 格式:   new 类名或者接口名(){     //重写类或者接口中 所有的 抽象方法;   };本质:  就…

0限流电阻 stm32_上/下拉电阻

除了前一节讨论的拉电阻基本使用方法外,上拉电阻也可以提升高电平的电压阈值,以便于前后级信号相匹配,比如,TTL逻辑电平驱动CMOS逻辑电平时,我们通常会添加一个上拉电阻R1,如下图所示:But Why&a…

天地与我并存/万物与我为一 2

http://blog.sina.com.cn/s/blog_17e792e010102y4lu.html 庖丁解牛 先秦:庄周 吾生也有涯,而知也无涯 。以有涯随无涯,殆已!已而为知者,殆而已矣!为善无近名,为恶无近刑。缘督以为经&#xff0c…

网段和子网的区别_电焊石笼网与普通石笼网区别

对于石笼网,每个人都会想到在河中,桥梁附近和大坝上充满石头的笼子结构。今天,我们谈论的是石笼网的一种电焊石笼网,它也是一种常见的石笼网,也被称为六边形石笼网。其功能与石笼网相同,但用法与普通石笼网…

jquery $(document).ready() 与window.onload的区别

转载博客:http://www.jb51.net/article/21628.htm Jquery中$(document).ready()的作用类似于传统JavaScript中的window.onload方法,不过与window.onload方法还是有区别的。 1.执行时间 window.onload必须等到页面内包括图片的所有元素加载完毕后…

小学三年级上册计算机计划,小学三年级数学上册教学计划

小学三年级数学上册教学计划一、班级情况分析这一学期我继续担任三年级数学教学工作,本班现有学生9人,其中男生3人,女生6人。三年级学生已经有两年的数学学习经历,对一些基础性的数学知识有了初步的认识。学生已经比较习惯于新教材…

centos7查看当前cpu运行模式_杂集:centos7中设置服务开机自启的两种方法,欢迎补充...

前言:在日常使用linux系统过程中,安装服务后系统不会自动启动服务的。就算手动启动了服务,只是当前生效,一旦服务器重启后,系统不会自动启动这些服务。如果每次重启服务器都要自己手动启动这些服务,一台还阔…