基于Python socket实现简易网络聊天室

下面是基于Python socket实现简易网络聊天室的完整攻略。

步骤一:实现基本的客户端和服务端

首先我们需要实现简单的客户端和服务端,可以让客户端发送消息给服务端,并让服务端把消息广播给所有的客户端。

客户端

import socket
import threading

IP = '127.0.0.1'
PORT = 1234

def send_message():
    while True:
        message = input('')
        client_socket.sendall(message.encode('utf-8'))

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))

threading.Thread(target=send_message).start()

while True:
    data = client_socket.recv(1024)
    print(data.decode('utf-8'))

服务端

import socket
import threading

IP = '127.0.0.1'
PORT = 1234

clients = []

def send_all(message, sender):
    for client in clients:
        if client != sender:
            client.sendall(message)

def handle_client(client, address):
    clients.append(client)
    while True:
        data = client.recv(1024)
        send_all(data, client)

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((IP, PORT))
server_socket.listen()

while True:
    client, address = server_socket.accept()
    threading.Thread(target=handle_client, args=(client, address)).start()

步骤二:添加用户名

接下来我们要让客户端能够设置一个用户名,显示在发送消息的前面。

我们可以在客户端和服务端加上一个username字段,这里我们用JSON格式来传递客户端和服务端之间的消息。

修改后的代码如下:

客户端

import socket
import threading
import json

IP = '127.0.0.1'
PORT = 1234

def send_message():
    while True:
        message = input('')
        data = {'username': username, 'message': message}
        client_socket.sendall(json.dumps(data).encode('utf-8'))

username = input('Enter your username: ')

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))

threading.Thread(target=send_message).start()

while True:
    data = client_socket.recv(1024)
    data = json.loads(data.decode('utf-8'))
    print(f'{data["username"]}: {data["message"]}')

服务端

import socket
import threading
import json

IP = '127.0.0.1'
PORT = 1234

clients = []

def send_all(data, sender):
    for client in clients:
        if client != sender:
            client.sendall(json.dumps(data).encode('utf-8'))

def handle_client(client, address):
    username = None
    while True:
        data = client.recv(1024)
        data = json.loads(data.decode('utf-8'))
        if username is None:
            username = data['username']
            clients.append(client)
        send_all(data, client)

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((IP, PORT))
server_socket.listen()

while True:
    client, address = server_socket.accept()
    threading.Thread(target=handle_client, args=(client, address)).start()

现在客户端在发送消息的时候会自动带上当前的用户名。

示例一:Ethan向聊天室中发送一条消息

Ethan 的客户端:

Enter your username: Ethan
Hello this is Ethan.

聊天室中其他客户端:

Ethan: Hello this is Ethan.

示例二:Mike向聊天室中发送一条消息

Mike 的客户端:

Enter your username: Mike
Hi, everyone!

聊天室中其他客户端:

Ethan: Hello this is Ethan.
Mike: Hi, everyone!

步骤三:支持私聊

最后我们再让聊天室支持私聊功能。

我们可以在客户端发送消息时,添加一个to字段,表示发给谁;在服务端收到消息时,判断一下是广播还是私聊,然后分别进行处理。

具体实现如下:

客户端

import socket
import threading
import json

IP = '127.0.0.1'
PORT = 1234

def send_message():
    while True:
        message = input('')
        data = {'username': username, 'message': message, 'to': to}
        client_socket.sendall(json.dumps(data).encode('utf-8'))

username = input('Enter your username: ')

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((IP, PORT))

threading.Thread(target=send_message).start()

while True:
    data = client_socket.recv(1024)
    data = json.loads(data.decode('utf-8'))
    if data['to'] == username or data['to'] == 'all':
        print(f'{data["username"]}: {data["message"]}')

服务端

import socket
import threading
import json

IP = '127.0.0.1'
PORT = 1234

clients = []

def send_all(data, sender):
    for client in clients:
        if client != sender:
            client.sendall(json.dumps(data).encode('utf-8'))

def handle_client(client, address):
    username = None
    while True:
        data = client.recv(1024)
        data = json.loads(data.decode('utf-8'))
        if username is None:
            username = data['username']
            clients.append(client)
        if data['to'] == 'all':
            send_all(data, client)
        else:
            for c in clients:
                if c != client and c.getpeername() == data['to']:
                    c.sendall(json.dumps(data).encode('utf-8'))
                    break

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((IP, PORT))
server_socket.listen()

while True:
    client, address = server_socket.accept()
    threading.Thread(target=handle_client, args=(client, address)).start()

现在客户端发送私聊消息时,需要在消息前加上@和用户名,例如@Ethan Hi,表示把消息发给 Ethan。

示例三:Ethan向聊天室中发送一条私聊消息

Ethan 的客户端:

Enter your username: Ethan
@Mike Hi Mike, how are you doing?

聊天室中其他客户端:

Ethan: @Mike Hi Mike, how are you doing?

Mike 的客户端上不会出现这条消息,因为这是一条私聊消息,只有 Mike 和 Ethan 能看到。

示例四:Mike向聊天室中发送一条私聊消息

Mike 的客户端:

Enter your username: Mike
@Ethan Hi Ethan, are you busy now?

聊天室中其他客户端:

Ethan: @Mike Hi Ethan, are you busy now?

以上就是基于Python socket实现简易网络聊天室的完整攻略,希望能对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于Python socket实现简易网络聊天室 - Python技术站

(0)
上一篇 2023年6月6日
下一篇 2023年6月6日

相关文章

  • Python中表示字符串的三种方法

    下面为您详细讲解Python中表示字符串的三种方法: 一、单引号表示字符串 Python中最常用的表示字符串的方法是使用单引号(’ ‘)。具体的示例见下: my_str = ‘Hello world!’ print(my_str) 上述代码将会输出 “Hello world!”。我们可以看到,使用单引号表示字符串时,字符串中包含的内容必须以单引号包括。 二、…

    python 2023年5月20日
    00
  • 完美解决Python matplotlib绘图时汉字显示不正常的问题

    针对Python matplotlib绘图时汉字显示不正常的问题,完美解决方案如下。 问题背景 在Python matplotlib绘图时,如果要输出的图表中包含有中文字符,那么有可能会遇到中文字符显示异常的问题,例如显示乱码或者方框替代等。这是因为matplotlib默认的字体库中没有中文字体,因此需要做一些额外的设置才能正常显示中文字符。 解决方案 要解…

    python 2023年6月13日
    00
  • Python调用服务接口的实例

    下面是关于“Python调用服务接口的实例”的完整攻略: 什么是服务接口 服务接口是计算机系统中不同软件之间互相交流的一种方式。在通信协议上,服务接口定义了通信的方式和规则。 在Web应用中,经常会使用服务接口来提供数据给前端,如RESTful API。而服务接口的调用也是Web开发过程中重要的一部分。 Python提供了很多第三方包来调用服务接口,比如re…

    python 2023年6月3日
    00
  • 用TensorFlow实现lasso回归和岭回归算法的示例

    下面是详细的攻略: 用TensorFlow实现lasso回归和岭回归算法的示例 Lasso回归和岭回归是常用的线性回归算法,可以用于特征选择和模型正则化。在TensorFlow中,我们可以使用tf.contrib.linear_optimizer模块实现Lasso回归和岭回归算法。本文将手把手教你如何使用TensorFlow实现Lasso回归和岭回归算法,并…

    python 2023年5月14日
    00
  • 在vscode中配置python环境过程解析

    下面是详细的“在vscode中配置python环境过程解析”的攻略: 1. 安装Python和VS Code 首先需要安装Python和VS Code。Python安装可以到官网下载对应版本的Python,安装即可。VS Code则可以到官网下载对应版本,安装也非常简单。 2. 安装Python插件 在VS Code中,我们需要安装Python插件,这个插件…

    python 2023年6月3日
    00
  • Python和Matlab实现蝙蝠算法的示例代码

    Python和Matlab实现蝙蝠算法的示例代码 蝙蝠算法是一种基于自然界蝙蝠群体行为的优化算法,用于解决优化问题。本文将介绍如何使用Python和Matlab实现蝙蝠算法,并提供两个示例说明。 蝙蝠算法的实现步骤 蝙蝠算法的实现步骤如下: 初始化蝙蝠群体。需要定义蝙蝠的位置、速度、频率和脉冲率等参数。 计算蝙蝠的适应度。需要根据蝙蝠的位置计算适应度。 更新…

    python 2023年5月14日
    00
  • 在 Ubuntu 18.04 上为 python 安装 mysqlclient 时出错

    【问题标题】:Error installing mysqlclient for python on Ubuntu 18.04在 Ubuntu 18.04 上为 python 安装 mysqlclient 时出错 【发布时间】:2023-04-05 08:26:01 【问题描述】: 我在 Ubuntu 上安装了 Python 2.7.15rci 和 Pytho…

    Python开发 2023年4月5日
    00
  • python中end=” “的含义及说明

    当在Python中使用print语句时,我们可以使用end参数来指定输出结束时要添加的字符(默认为换行符\n)。 在默认情况下,当我们使用print语句输出多个变量时,Python会自动用空格分隔它们: name = "Alice" age = 24 print(name, age) # 输出 Alice 24 反之,我们也可以通过设置e…

    python 2023年6月13日
    00
合作推广
合作推广
分享本页
返回顶部