基于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
打开
本作品由happyZYM采用知识共享 署名-非商业性使用-相同方式共享 4.0 (CC BY-NC-SA 4.0) 国际许可协议(镜像(简单版)镜像(完整版))进行许可。
转载请注明出处:https://www.cnblogs.com/happyZYM/p/15416510.html (近乎)全文转载而非引用的请在文首添加出处链接。