基于python的机房聊天工具

适用范围:机房无外网、无U盘接口,但有python。电脑是windows的。

完整版

代码如下:

import socket
import sys
import time
import getopt
import os
from threading import Thread
"""
修改自https://blog.csdn.net/songling515010475/article/details/106426124
主要有以下改进:
- 有消息记录
- 支持多个客户端
- 客户端随意登出而服务端不Crash
"""
class WebChat:
    username=""
    server_handles=[]
    addrs=[]
    que=[]
    server=""
    realname=True # 实名制
    f=""
    online=[]
    #输出帮助信息
    def usage(self):
        print("help info : python webChat.py -h")
        print("client : python webChat.py -t [target] -p [port]")
        print("server : python webChat.py -lp [port]")
        sys.exit()
 
    #聊天客户端
    def webChatClient(self, target, port):
        #创建socket套接字
        client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #连接服务器
        client.connect((target, port))
        print("[*] try to connect the target......")
        #接收服务器发过来的信息
        response = client.recv(1024)
        print(response.decode())
        self.username=input("请输入用户名(不可有空格)>")
        self.f=open("LogOf"+self.username+".txt",mode="a")
        os.system("start python webChat.py -s "+"LogOf"+self.username+".txt")
        print("现在你可以输入消息了,按Enter发送")
        #创建发送消息的线程
        t = Thread(target=self.uploadData, args=(client,))
        #指定当前主线程结束时退出子进程
        t.setDaemon(True)
        #启动线程
        t.start()
 
        # 创建接收消息的线程
        c = Thread(target=self.downloadData, args=("",client,))
        c.setDaemon(True)
        c.start()
        try:
            while True:
                time.sleep(10000)
        #KeyboardInterrupt用来接收Ctrl+c,当接收到命令时就会捕获,并退出
        except KeyboardInterrupt:
            sys.exit()
    #聊天服务端
    def webChatServer(self, port):
        self.f=open("serverlog.txt",mode="a")
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.bind(("0.0.0.0",port))
        self.server.listen(255)
        # 不断连接
        l=Thread(target=self.acceptclients,args=())
        l.setDaemon(True)
        l.start()
        # 创建发送消息的线程
        t = Thread(target=self.sendData, args=())
        # 指定当前主线程结束时退出子进程
        t.setDaemon(True)
        # 启动线程
        t.start()
        try:
            time.sleep(10000)
        # KeyboardInterrupt用来接收Ctrl+c,当接收到命令时就会捕获,并退出
        except KeyboardInterrupt:
            sys.exit()
    #不断连接
    def acceptclients(self):
        while True:
            print("[*] Listening on 0.0.0.0:%d"%port)
            server_handle, addr = self.server.accept()
            print("[*] Accept connection from %s:%d"%(addr[0], addr[1]))
            server_handle.send(b"[*] connection successful...")
            self.server_handles.append(server_handle)
            self.addrs.append(addr)
            self.online.append(1)
            # 创建接收消息的线程
            cx = Thread(target=self.recvaData, args=(self.server_handles[-1],self.addrs[-1],len(self.addrs)-1))
            cx.setDaemon(True)
            cx.start()
    #服务端发送数据涵数
    def sendData(self):
        while True:
            if len(self.que):
                data = self.que[0]
                data = data.encode('utf-8')
                for i in range(len(self.server_handles)):
                    if self.online[i]:
                        self.server_handles[i].send(data)
                self.que=self.que[1:]
 
    #服务端接收数据涵数   
    def recvaData(self,socket,addr,it):
        while True:
            try:
                response=socket.recv(1024)
            except ConnectionResetError:
                self.online[it]=0
                return 0
            print("Message received:",response)
            print("Message received:",response,file=self.f)
            self.f.close()
            self.f=open("serverlog.txt",mode="a")
            if response:
                response = response.decode()
                response="At "+time.asctime( time.localtime(time.time()) )+response
                if self.realname:
                    response="From "+str(addr[0])+":"+str(addr[1])+" "+response
                self.que.append(response)
                
    #客户端发送数据涵数
    def uploadData(self, socket):
        while True:
            data = input(">>> ")
            if data == "@reshow":
                os.system("start python webChat.py -s "+"LogOf"+self.username+".txt")
            else:
                data = (" | "+self.username+" >\n"+data+"\n"+57*"_").encode('utf-8')
                socket.send(data)
 
    #客户端接收数据涵数
    def downloadData(self,name, socket):
        while True:
            response = socket.recv(1024)
            if response:
                response = response.decode()
                print(name,response,file=self.f)
                self.f.close()
                self.f=open("LogOf"+self.username+".txt",mode="a")
 
if __name__ == "__main__":
    target = ""
    port = 0
    listen = False
    help = False
    opts, args = getopt.getopt(sys.argv[1:], "t:p:lh:s") #利用getopt模块获取从命令行中的参数
    for o,a in opts:
        if o == "-t":
            target = a
        elif o == "-p":
            port = int(a)
        elif o == "-l":
            listen = True
        elif o == "-h":
            help == True
        elif o=="-s":
            os.system("title "+sys.argv[2][5:-4])
            lu=0
            while True:
                while True:
                    time.sleep(0.1)
                    x=os.path.getmtime(sys.argv[2])
                    if x>lu:
                        lu=x
                        break
                os.system("cls")
                os.system("type "+sys.argv[2])
        else:
            assert False, "Unhandled Option"
    test = WebChat()
    if help:#输出帮助信息
        test.usage()
    elif listen:#调用服务器
        test.webChatServer(port)
    else:#调用客户端
        test.webChatClient(target, port)

使用示例:
让某位手速快的童鞋先敲好服务器,运行python webChat.py -lp [端口号]
然后其他童鞋敲好客户端后,运行python webChat.py -t [服务器ip号] -p [端口号]

机房10分钟内敲完版

代码:

import socket,sys,time,getopt,os
from threading import Thread
class WC:
    v1,v6,f,v2,v3,v4,vX="","","",[],[],[],[]
    v5=1 # 实名制开关
    def f1(self, vB, vC):
        vA=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        vA.connect((vB, vC))
        v9=vA.recv(1024)
        print(v9.decode())
        self.v1=input("用户名?>")
        self.f=open("LogOf"+self.v1+".txt",mode="a")
        os.system("start python webChat.py -s "+"LogOf"+self.v1+".txt")
        print("输入消息并按Enter发送")# 可删去
        t=Thread(target=self.f6, args=(vA,))
        t.setDaemon(1)
        t.start()
        c=Thread(target=self.f7, args=("",vA,))
        c.setDaemon(1)
        c.start()
        try:
            while 1: time.sleep(10000)
        except KeyboardInterrupt:
            sys.exit()
    def f2(self, vC):
        self.f=open("serverlog.txt",mode="a")
        self.v6 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.v6.bind(("0.0.0.0",vC))
        self.v6.listen(255)
        l=Thread(target=self.f3,args=())
        l.setDaemon(1)
        l.start()
        t=Thread(target=self.f4, args=())
        t.setDaemon(1)
        t.start()
        try:
            while 1: time.sleep(10000)
        except KeyboardInterrupt:
            sys.exit()
    def f3(self):
        while 1:
            v7,v8=self.v6.accept()
            v7.send(b"[*] connection successful...")
            self.v2.append(v7)
            self.v3.append(v8)
            self.vX.append(1)
            cx = Thread(target=self.f5, args=(self.v2[-1],self.v3[-1],len(self.v2)-1))
            cx.setDaemon(1)
            cx.start()
    def f4(self):
        while 1:
            if len(self.v4):
                vK = self.v4[0].encode('utf-8')
                for i in range(len(self.v2)):
                    if self.vX[i]: self.v2[i].send(vK)
                self.v4=self.v4[1:]
    def f5(self,vH,v8,it):
        while 1:
            try:
                v9=vH.recv(1024)
            except ConnectionResetError:
                self.vX[it]=0
                return 0
            print(v9,file=self.f)
            self.f.flush()
            if v9:
                v9="At "+time.asctime( time.localtime(time.time()) )+v9.decode()
                if self.v5:
                    v9="From "+str(v8[0])+":"+str(v8[1])+" "+v9
                self.v4.append(v9)
    def f6(self, vH):
        while 1:
            vK = input(">>> ")
            if vK == "@#RS": os.system("start python webChat.py -s LogOf"+self.v1+".txt")
            else: vH.send((" | "+self.v1+" >\n"+vK+"\n"+57*"_").encode('utf-8'))
    def f7(self,vJ, vH):
        while 1:
            v9 = vH.recv(1024)
            if v9:
                print(vJ,v9.decode(),file=self.f)
                self.f.close()
                self.f=open("LogOf"+self.v1+".txt",mode="a")
 
vB,vC,vD="",0,0
vE,vF=getopt.getopt(sys.argv[1:], "t:p:lh:s")
for o,a in vE:
    if o == "-t": vB=a
    elif o == "-p": vC=int(a)
    elif o == "-l": vD=1
    elif o=="-s":
        os.system("title "+sys.argv[2][5:-4])
        lu=0
        while 1:
            while 1:
                time.sleep(0.1)
                x=os.path.getmtime(sys.argv[2])
                if x>lu:
                    lu=x
                    break
            os.system("cls")
            os.system("type "+sys.argv[2])
    else: pass
vG = WC()
if vD: vG.f2(vC)
else: vG.f1(vB,vC)

其中,不需要自己的电脑做服务器的同学只要有:

import socket,sys,time,getopt,os
from threading import Thread
class WC:
    v1,v6,f,v2,v3,v4="","","",[],[],[]
    v5=1 # 实名制开关
    def f1(self, vB, vC):
        vA=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        vA.connect((vB, vC))
        v9=vA.recv(1024)
        print(v9.decode())
        self.v1=input("用户名?>")# 用户名不可有空格
        self.f=open("LogOf"+self.v1+".txt",mode="a")
        os.system("start python webChat.py -s "+"LogOf"+self.v1+".txt")
        print("输入消息并按Enter发送")# 可删去
        t=Thread(target=self.f6, args=(vA,))
        t.setDaemon(1)
        t.start()
        c=Thread(target=self.f7, args=("",vA,))
        c.setDaemon(1)
        c.start()
        try:
            while 1: time.sleep(10000)
        except KeyboardInterrupt:
            sys.exit()
    def f3(self):
        while 1:
            v7,v8=self.v6.accept()
            v7.send(b"[*] connection successful...")
            self.v2.append(v7)
            self.v3.append(v8)
            cx = Thread(target=self.f5, args=(self.v2[-1],self.v3[-1],))
            cx.setDaemon(1)
            cx.start()
    def f6(self, vH):
        while 1:
            vK = input(">>> ")
            if vK == "@#RS": os.system("start python webChat.py -s LogOf"+self.v1+".txt")
            else: vH.send((" | "+self.v1+" >\n"+vK+"\n"+57*"_").encode('utf-8'))
    def f7(self,vJ, vH):
        while 1:
            v9 = vH.recv(1024)
            if v9:
                print(vJ,v9.decode(),file=self.f)
                self.f.close()
                self.f=open("LogOf"+self.v1+".txt",mode="a")
 
vB,vC="",0
vE,vF=getopt.getopt(sys.argv[1:], "t:p:s")
for o,a in vE:
    if o == "-t": vB=a
    elif o == "-p": vC=int(a)
    elif o=="-s":
        os.system("title "+sys.argv[2][5:-4])
        lu=0
        while 1:
            while 1:
                time.sleep(0.1)
                x=os.path.getmtime(sys.argv[2])
                if x>lu:
                    lu=x
                    break
            os.system("cls")
            os.system("type "+sys.argv[2])
    else: pass
WC().f1(vB,vC)

使用方式:

  • 客户端:新建文件webChat.py,输入对应代码,保存,在同一文件夹下新建文件start.bat,输入python webChat.py -t [服务器ip号] -p [端口号](这两个数字在信息课前商量好),例如python webChat.py -t 192.168.1.252 -p 2333,保存。等服务器运行后(可以预先约定一个时间,比如上课15min后),双击start.bat打开
  • 服务端:新建文件webChat.py,输入对应代码,保存,在同一文件夹下新建文件startserver.bat,输入python webChat.py -lp [端口号](这个数字在信息课前商量好,记得用ipconfig等指令查看自己的ip告诉其他同学),例如python webChat.py -lp 2333,保存。双击startserver.bat打开
posted @ 2021-10-17 11:32  happyZYM  阅读(221)  评论(0编辑  收藏  举报