Python socket实现聊天服务器(核心编程学习第二章)

Python socket实现聊天服务器(核心编程学习第二章)

这是第二章书后作业–实现一个聊天服务器,客户端与客户端可进行聊天

功能:注册,登录,全域广播(相当于一个群),获取服务器时间
下面是服务器端(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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值