python

教你用python写一个聊天工具

2023-01-06  本文已影响0人  fakeProgramer
【目标】使用socket套接字写个简易的聊天工具,实现全双工收发数据
语言:python
包:socket threading time
代码注释写的比较详细,这里为了方便所有人都能看懂,大佬可忽略

搭建服务端

本文用到的socket、threading等都是python内置库,直接import即可;
socket用于构建链接服务;
threading用于实现收发消息的并发运行;
话不多说,直接上代码:
import socket as sk
import threading
import time

def get_host_info():   # 获取本机IP的函数
    HOSTNAME = sk.gethostname()   # gethostname()方法,获取主机信息
    HOST = sk.gethostbyname(HOSTNAME)   # gethostbyname()方法,解析主机信息获得IP
    print(HOST)
    return HOST

def recv_message(conn, size):
    while True:
        recv_msg = conn.recv(size).decode('utf-8')   # 接收消息并解码
        print(f'客户端:{recv_msg}')   # 接收消息有内容就打印出来
        time.sleep(0.1)
def send_message(conn):
    while True:
        send_msg = input('')   # 阻塞等待用户输入
        if send_msg != '':   # 输入内容不为空字符串时,执行发送,否则继续循环
            conn.send(send_msg.encode('utf-8'))   # UTF-8编码消息并传输
            time.sleep(0.1)
        else:
            pass

HOST = get_host_info()   # 获取本机IP
POST = 8997   # 定义一个端口号
ADDR = (HOST, POST)
SIZE = 1024   # 定义最大传输数据(bytes)
sever = sk.socket(family=sk.AF_INET, type=sk.SOCK_STREAM)    # 创建套接字对象(AF_INET——IPV4,SOCK_STREAM——TCP连接)
sever.bind(ADDR)   # 套接字对象绑定IP和端口号
sever.listen(10)   # 开始监听客户端的连接请求
conn, addr = sever.accept()   # 阻塞并等待连接,解析客户端主机信息,连接成功
# conn是新的套接字对象,用来发送和接收数据;addr是客户端的主机地址
print('客户端已连接。')

t1 = threading.Thread(target=recv_message, args=(conn, SIZE))   # 构造双线程让t1和t2并行,从而实现全双工
t2 = threading.Thread(target=send_message, args=(conn,))

if __name__ == '__main__':
    t1.start()
    t2.start()

搭建客户端

和服务端的逻辑一样,把收发功能和线程再写一遍
import socket as sk
import threading
import time

def recv_message(client, size):
    while True:
        recv_msg = client.recv(size).decode('utf-8')
        print(f'服务端:{recv_msg}')
        time.sleep(0.1)

def send_message(client):
    while True:
        send_msg = input('')
        if send_msg != '':
            client.send(send_msg.encode('utf-8'))   # 发信函数会在此阻塞,等待信息输入后再循环
            time.sleep(0.1)
        else:
            pass

client = sk.socket(family=sk.AF_INET, type=sk.SOCK_STREAM)
HOST = ''   # 将服务端的HOST写进来
POST = 8997
ADDR = (HOST, POST)
SIZE = 1024
client.connect(ADDR)
print('服务端已连接。')

t1 = threading.Thread(target=recv_message, args=(client,SIZE))
t2 = threading.Thread(target=send_message, args=(client,))
t1.start()
t2.start()

注意事项

1、服务端和客户端都启动的情况下,才能实现聊天。
2、由于没写退出功能,任何一方关闭程序都自动断开连接。
3、如果正在输入时来消息,会打断输入过程。这是由于未搭建前端文本框导致的输入和输出信息重叠。一个比较简单的解决方案是tkinter搭建一个前端交互界面,将聊天框和输入框分离,以解决打断输入的问题。后面我也会再写一篇,记录tkinter的学习心得。
4、由于服务端程序没有固定的IP地址,目前工具仅能实现同一路由器下的局域网聊天。想实现跨网络还是要在专属服务器上搭建。

上一篇下一篇

猜你喜欢

热点阅读