功能:注册,登录,全域广播(相当于一个群),获取服务器时间
下面是服务器端(Server)的代码
–注意,其中获取用户数据的代码是我自己写的sqlite3类库和MyLog类库。请前往底部获取。
import socket
import threading
import time
import sqlite3
import MyPackage.MySQLite as SQL
import os
from MyPackage.MyLog import *
class Server:
def __init__(self,Host:str,Port:int,BufferSize:int):
self.tcpsok = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建服务器套接字
self.BufferSize=BufferSize
Addr = (Host, Port)
self.tcpsok.bind(Addr) #将地址(主机名,端口号对)绑定到套接字上
ULog=Log("UserLog.db","Log") #连接数据库
self.ServerLog={
}#记录连接用户
self.Log=Log("UserLog.db","Log")#连接数据库
def StartListen(self,Count:int):
self.tcpsok.listen(Count)#开始监听
def StartAccept(self):
while True:
print("Waiting...")
tcpclient,addr=self.tcpsok.accept()
username=self.Log.SignIn(tcpclient)
self.ServerLog[username]=tcpclient
locals()[addr[1]]=threading.Thread(target=Server.NewCommnubication,args=(self,tcpclient,username)).start()#创建新进程以开启一个会话,记录到一个动态生成的变量中
def NewCommnubication(self,tcpclient:socket.socket,username):
print("A New Connected by: ",username)
tcpclient.send(bytes('Welcom\nThere have some Users: %s \n'%(self.ServerLog.keys()),'utf-8'))#发送欢迎信息
threading.Thread(target=Server.GlobleBroadCast,args=(self,"{0} Online".format(username))).start()
while True:#实现服务器和客户端的交互
try:
data=tcpclient.recv(self.BufferSize)
data=Server.Command(self,tcpclient,data)
except ConnectionResetError:
for i in self.ServerLog:
if self.ServerLog[i] == tcpclient:
self.ServerLog[i].close()
del(self.ServerLog[i])
self.GlobleBroadCast(i+" Offline")
print(i+" Offline")
break
break
def CloseServer(self,tcpsok:socket.socket):
tcpsok.close()
def PrintUsers(self):
print(self.Log)
def GlobleBroadCast(self,Text:str):
ctext=time.ctime()+">>"+Text
for u in self.ServerLog:
self.ServerLog[u].send(bytes(ctext,'utf-8'))
def Command(self,tcpclient:socket.socket,Comm:str):
CommandList=['discon','time']
if Comm==b'time':
print("Return Time")
tcpclient.send(bytes(time.ctime(),'UTF-8'))
if Comm.startswith(b'rChat'):
threading.Thread(target=Server.Chat,args=(self,tcpclient,Comm)).start()
def Chat(self,tcpclient:socket.socket,Comm):
Comm=str(Comm,'utf-8')
Comm=Comm[6:]
for i in self.ServerLog:
if self.ServerLog[i]==tcpclient:
name=i
name=name+": "+Comm
Comm=name
del (name)
Server.GlobleBroadCast(self,Comm)
下面是客户端代码(Client)
import socket
from threading import Thread
class MyClient:
def __init__(self,Host:str,Port:int,BufferSize:int):
self.Host=Host
self.Port=Port
self.BufferSize=BufferSize
self.Tcpclient=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
self.Addr=(self.Host,self.Port)
def Connenct(self):
tcp=self.Tcpclient.connect(self.Addr)
t1=Thread(target=MyClient.Recv,args=(self,0))
t2=Thread(target=MyClient.Send,args=(self,0))
t1.start()
t2.start()
def Close(self):
self.Tcpclient.close()
def Recv(self,u):
while True:
try:
recv = self.Tcpclient.recv(self.BufferSize)
print(str(recv, 'UTF-8'))
except ConnectionAbortedError:
print("Connenction Closed")
break;
def Send(self,u):
while True:
recv = input("> ")
if recv.startswith("r "):
recv=recv[2:]
data="rChat "
data=data+recv
recv=data
del(data)
if recv=='exit':
MyClient.Close(self)
return 0
self.Tcpclient.send(bytes(recv, 'UTF-8'))
`
我的sqlite3类库
import sqlite3
class SQLite:
def __init__(self,Path:str):
self.sql=sqlite3
self.Path=Path
self.conn = self.sql.connect(self.Path)
self.conn.close()
self.TName=''
def ConnectDataBase(self):
self.conn=self.sql.connect(self.Path)
def SetTargetTable(self,TableName:str):
self.TName=TableName
def Close(self):
self.conn.close()
def CreateTable(self,TableName:str,ColumsNameAndType:str):
SQLite.ConnectDataBase(self)
cur=self.conn.cursor()
cur.execute("Create Table %s(%s)"%(TableName,ColumsNameAndType))
self.conn.commit()
self.conn.close()
def NewColum(self,Name,Type):
SQLite.ConnectDataBase(self)
cur=self.conn.cursor()
cur.execute('Alter Table %s add %s %s'%(self.TName,Name,Type))
self.conn.commit()
self.conn.close()
def Insert(self,CoulumName:str,Values:str):
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("Insert into {0}('{1}') values('{2}')".format(self.TName,CoulumName,Values))
self.conn.commit()
self.conn.close()
def Update(self,ColumName:str,Value:str,XColumName:str,XValue:str):
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("Update %s set %s='%s' Where %s='%s' "%(self.TName,ColumName,Value,XColumName,XValue))
self.conn.commit()
self.conn.close()
def GetOneData(self,ColumName:str,XColumName:str,XValue:str)->str:
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("select %s from %s where %s='%s'" % ( ColumName, self.TName, XColumName, XValue))
data=cur.fetchall()
self.conn.close()
return data
def GetOneColumn(self,ColumnName:str)->list:
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("select %s from %s " % (ColumnName, self.TName))
data = cur.fetchall()
self.conn.close()
return data
def GetAllTableName(self)->list:
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("Select name from sqlite_master where type='table' Order by name")
data = cur.fetchall()
self.conn.close()
return data
def GetAllColumns(self):
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("pragma table_info({0})".format(self.TName))
data = list(cur.fetchall())
self.conn.close()
return data
def DeleteData(self,ColumnName:str,Values:str):
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("delete from {0} where {1}='{2}'".format(self.TName,ColumnName,Values))
self.conn.commit()
self.conn.close()
return data
def DeleteDataAccurately(self,ColumName:str,Value:str,XColumName:str,XValue:str):
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("Delete From {0} Where {1}='{2}' and {3}='{4}'".format(TableName, ColumnName,Value,XColumnName,XValue))
self.conn.commit()
self.conn.close()
def DeleteColumn(self,ColumnName):
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("Alter table drop COLUMN {0}".format(ColumnName))
self.conn.commit()
self.conn.close()
def DeleteRow(self,RowName,RowValues):
SQLite.ConnectDataBase(self)
cur = self.conn.cursor()
cur.execute("Delete from '{0}' where {1}='{2}'".format(self.TName,RowName,RowValues))
self.conn.commit()
self.conn.close()
MyLog类库
import sqlite3
import MyPackage.MySQLite as SQL
import os
import socket
class Log:
def __init__(self,DBPath,TableName:str):
self.DBPath=DBPath
self.Log={
}
self.UserName=""
self.BufferSize=1024
self.TableName=TableName
def LoadLog(self,Name:str,sock:socket.socket):
self.Log[Name]=sock
def SignUp(self,tcpclient:socket.socket):#注册新用户
data="Please input your UserName:"
tcpclient.send(bytes(data,'utf-8'))
username=str(tcpclient.recv(self.BufferSize),'utf-8')
data="Please input your PassWord:"
tcpclient.send(bytes(data, 'utf-8'))
pwd= str(tcpclient.recv(self.BufferSize), 'utf-8')
sql=SQL.SQLite(self.DBPath)
sql.SetTargetTable(self.TableName)
try:
sql.Insert('Name',username)
sql.Update('PWD',pwd,'Name',username)
except sqlite3.IntegrityError:
data="The UserName {0} is already exists,please rename:"
tcpclient.send(bytes(data, 'utf-8'))
Log.SignUp(self,tcpclient)
data="Register Success! Please Sign-In\n---------------------------------------------"
tcpclient.send(bytes(data, 'utf-8'))
Log.SignIn(self,tcpclient)
def SignIn(self,tcpclient:socket.socket):
sql = SQL.SQLite(self.DBPath)
sql.SetTargetTable(self.TableName)
data="Please input your UserName:\n"
tcpclient.send(bytes(data,'utf-8'))
username = str(tcpclient.recv(self.BufferSize),'utf-8')
data="Please input your PassWord:\n"
tcpclient.send(bytes(data,'utf-8'))
pwd = str(tcpclient.recv(self.BufferSize),'utf-8')
inputpwd=""
if sql.GetOneData('Name','Name',username) != []:
while True:
self.UserName=username
inputpwd = str(list(sql.GetOneData("PWD", 'Name', username)[0])[0])
if inputpwd!=pwd:
print(inputpwd)
data="PassWord wrong,please rewrite your password:"
tcpclient.send(bytes(data,'utf-8'))
pwd=str(tcpclient.recv(self.BufferSize),'utf-8')
else:
self.UserName=username
break
else:
data="No User Named {0},Rewrite(w) or Register(r)?".format(username)
tcpclient.send(bytes(data,'utf-8'))
if str(tcpclient.recv(self.BufferSize),'utf-8') is not 'w':
Log.SignUp(self,tcpclient)
else:
Log.SignIn(self,tcpclient)
return username