HJ07 发表于 2022-2-27 12:19

一个简单的网络聊天室软件

这是一个简单的网络多人聊天室软件,包括服务器端server.py和客户端client.py。
```py
# server.py
# Coco07
# 2020.9.17

import socket
import threading
import time

MAX_GUEST_N = 2
PASSWORLD_ACC = 'zxcvbnm'
SYS_BYTES = 16
MESSAGE_BYTES = 5120

guest_conns = []
guest_names = []

def broadcast(msg):
    for i in guest_conns:
      try:
            i.send(msg.encode())
      except:
            pass

def msg_proc(msg, conn, name):
    try:
      if msg == 'M' or msg == 'T':
            msg = name+':'+msg
            broadcast('M'+msg)
      elif msg == 'I':
            msg = 'M[会话信息]会话人数:'+str(len(guest_conns))
            for i in guest_names:
                if i == name:
                  msg += '\n[会话信息]I'
                else:
                  msg += '\n[会话信息]Guest'
                msg += ' '+i
            conn.send(msg.encode())
            msg = 'M[服务器信息]服务器地址:'+str((host_name, host_port))
            conn.send(msg.encode())
      else:
            pass
    except:
      pass

def guest(conn, addr, name):
    while True:
      try:
            name = conn.recv(64).decode()
            if not name in guest_names:
                conn.send('nameok'.encode())
                guest_names.append(name)
                break
            else:
                conn.send('nameerr'.encode())
                print(addr, '昵称设置失败')
      except:
            pass
    guest_conns.append(conn)
    print(addr, name+'进入会话')
    broadcast('M[服务器消息]'+name+'进入会话')
    while True:
      try:
            msg = conn.recv(MESSAGE_BYTES).decode()
            if not msg:
                continue
            msg_proc(msg, conn, name)
            print(addr, msg)
      except:
            guest_conns.remove(conn)
            guest_names.remove(name)
            print(addr, name+'退出会话')
            broadcast('M[服务器消息]'+name+'退出会话')
            break


# main #

print('Server Coco07\n')

print('端口:', end='')

host_name = socket.gethostname()
host_port = int(input())

sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.bind((host_name, host_port))
sk.listen(5)

print('此服务器:', (host_name, host_port))
print('等待连接...')

while True:
    try:
      conn, addr = sk.accept()
      print(addr, '尝试连接')
      passworld = conn.recv(SYS_BYTES).decode()
      if passworld == PASSWORLD_ACC:
            conn.send('y'.encode())
            t = threading.Thread(target=guest, args=(conn, addr, ''))
            t.start()
      else:
            print(addr, '密匙错误')
            conn.send('n'.encode())
    except:
      pass
      time.sleep(2)

sk.close()
```

```py
# client.py
# Coco07
# 2020.9.17

import socket
import threading

PASSWORLD_ACC = 'zxcvbnm'
SYS_BYTES = 16
MESSAGE_BYTES = 5120

def send_msg():
    while True:
      try:
            msg = input()
            if not msg:
                continue
            elif msg == 'text':
                msg = 'T'
                while True:
                  temp = input()
                  if temp == 'end':
                        break
                  msg = msg+'\n'+temp
                sk.send(msg.encode())
            elif msg == 'info':
                sk.send('I'.encode())
            elif msg == 'exit':
                sk.close()
                break
            else:
                msg = 'M'+msg
                sk.send(msg.encode())
      except ConnectionResetError:
            print('[本地消息]找不到服务器')
            break
      except ConnectionAbortedError:
            break

def recv_msg():
    while True:
      try:
            msg = sk.recv(MESSAGE_BYTES).decode()
            if not msg:
                continue
            elif msg == 'M':
                print(msg)
      except ConnectionResetError:
            print('[本地消息]找不到服务器')
            break
      except ConnectionAbortedError:
            break


print('Client Coco07\n')

print('服务器地址:', end='')
serverIP = input()
print('端口:', end='')
serverPort = int(input())

print('正在连接服务器...')

sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk.connect((serverIP, serverPort))

print('[本地消息]已找到服务器')

sk.send(PASSWORLD_ACC.encode())
link_mood = sk.recv(SYS_BYTES).decode()

if link_mood == 'y':
    print('[本地消息]服务器已连接')

    while True:
      print('输入昵称:', end='')
      myname = input()
      sk.send(myname.encode())
      if sk.recv(SYS_BYTES).decode() == 'nameok':
            break
      else:
            print('[本地消息]昵称设置失败')
    print('[本地消息]昵称设置成功')

    t_send = threading.Thread(target=send_msg)
    t_recv = threading.Thread(target=recv_msg)
    ts =
    for t in ts:
      t.setDaemon(True)
      t.start()
    t.join()
else:
    print('[本地消息]密匙错误')
    exit()

sk.close()
```

附:Pyinstaller

我用(https://www.pyinstaller.org/)把它转换为exe文件。在cmd中输入以下命令以在[清华大学开源软件镜像站](https://mirrors.tuna.tsinghua.edu.cn/)下载。

```
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pyinstaller
```

下载完成后cmd转到XXX.py的目录使用以下命令

```
pyinstaller -F -i ICON.ico XXX.py
```

\--noconsole即去掉cmd命令窗口。

feob 发表于 2022-2-27 12:53

感谢分享

cyl279 发表于 2022-2-27 12:53


感谢分享

怒火燃烧 发表于 2022-2-27 12:59

谢谢分享,学习了!!

helian147 发表于 2022-2-27 13:06

想找个手机上的聊天软件的源码,一直没找到....

iDataLord 发表于 2022-2-27 13:09

谢谢分享,怀念当年的聊天室。

seferrazie1 发表于 2022-2-27 13:12

感谢分享,学习了

你的明媚我的城 发表于 2022-2-27 13:22

感谢分享 学习了呀

Kanye 发表于 2022-2-27 13:39

So classical

止戈ing 发表于 2022-2-27 14:26

学习了我去试试~
页: [1] 2 3
查看完整版本: 一个简单的网络聊天室软件