├── db.sql ├── icons ├── img.png ├── qq.png ├── chat.png ├── copy.png ├── edit.png ├── group.png ├── hd_1.png ├── user.png ├── arrow_d.png ├── arrow_r.png └── delete.png ├── images ├── 381272362.jpg ├── 467619218.jpg ├── 1227263052.jpg ├── 1675793701.jpg ├── 1925614202.jpg ├── 聊天室桌面端登录界面.png └── 聊天室桌面端聊天界面.png ├── __pycache__ ├── testWidgets.cpython-35.pyc └── customWidget.cpython-35.pyc ├── README.md ├── client.py ├── testWidgets.py ├── qtclient.py ├── server.py ├── customWidget.py └── mysql.sql /db.sql: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/db.sql -------------------------------------------------------------------------------- /icons/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/img.png -------------------------------------------------------------------------------- /icons/qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/qq.png -------------------------------------------------------------------------------- /icons/chat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/chat.png -------------------------------------------------------------------------------- /icons/copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/copy.png -------------------------------------------------------------------------------- /icons/edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/edit.png -------------------------------------------------------------------------------- /icons/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/group.png -------------------------------------------------------------------------------- /icons/hd_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/hd_1.png -------------------------------------------------------------------------------- /icons/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/user.png -------------------------------------------------------------------------------- /icons/arrow_d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/arrow_d.png -------------------------------------------------------------------------------- /icons/arrow_r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/arrow_r.png -------------------------------------------------------------------------------- /icons/delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/icons/delete.png -------------------------------------------------------------------------------- /images/381272362.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/images/381272362.jpg -------------------------------------------------------------------------------- /images/467619218.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/images/467619218.jpg -------------------------------------------------------------------------------- /images/1227263052.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/images/1227263052.jpg -------------------------------------------------------------------------------- /images/1675793701.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/images/1675793701.jpg -------------------------------------------------------------------------------- /images/1925614202.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/images/1925614202.jpg -------------------------------------------------------------------------------- /images/聊天室桌面端登录界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/images/聊天室桌面端登录界面.png -------------------------------------------------------------------------------- /images/聊天室桌面端聊天界面.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/images/聊天室桌面端聊天界面.png -------------------------------------------------------------------------------- /__pycache__/testWidgets.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/__pycache__/testWidgets.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/customWidget.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataXujing/chatRoom/master/__pycache__/customWidget.cpython-35.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | python聊天室的源代码:为了方便浏览,已经从[kali库](https://github.com/JINLINBI/kali/tree/master/network)中独立抽取出来,并且删除了一些不必要的文件。 2 | 3 | #程序运行截图 4 | 安卓端登录界面:![](https://github.com/JINLINBI/chatRoom/blob/master/images/1227263052.jpg "安卓端登录界面截图") 5 | 安卓端功能界面:![](https://github.com/JINLINBI/chatRoom/blob/master/images/1675793701.jpg "安卓端功能界面截图") 6 | 安卓端聊天界面:![](https://github.com/JINLINBI/chatRoom/blob/master/images/1925614202.jpg "安卓端聊天界面截图") 7 | 8 | 9 | 桌面端登录界面:![](https://github.com/JINLINBI/chatRoom/blob/master/images/%E8%81%8A%E5%A4%A9%E5%AE%A4%E6%A1%8C%E9%9D%A2%E7%AB%AF%E7%99%BB%E5%BD%95%E7%95%8C%E9%9D%A2.png "桌面端登录界面") 10 | 桌面端聊天界面:![](https://github.com/JINLINBI/chatRoom/blob/master/images/%E8%81%8A%E5%A4%A9%E5%AE%A4%E6%A1%8C%E9%9D%A2%E7%AB%AF%E8%81%8A%E5%A4%A9%E7%95%8C%E9%9D%A2.png "桌面端聊天界面") 11 | -------------------------------------------------------------------------------- /client.py: -------------------------------------------------------------------------------- 1 | import socket, select, string, sys,struct 2 | import pickle 3 | 4 | def send(channel,*args): 5 | buffers=pickle.dumps(args) 6 | value=socket.htonl(len(buffers)) 7 | size=struct.pack("L",value) 8 | channel.send(size) 9 | channel.send(buffers) 10 | def prompt() : 11 | sys.stdout.write('') 12 | sys.stdout.flush() 13 | if __name__ == "__main__": 14 | if(len(sys.argv) < 3) : 15 | print('Usage : filename hostname port ' ) 16 | sys.exit() 17 | host = sys.argv[1] 18 | port = int(sys.argv[2]) 19 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 20 | s.settimeout(2) 21 | try : 22 | s.connect((host, port)) 23 | except : 24 | print('Unable to connect') 25 | sys.exit() 26 | print( 'Connected to remote host. Start sending messages' ) 27 | prompt() 28 | while True: 29 | rlist = [sys.stdin, s] 30 | read_list, write_list, error_list = select.select(rlist , [], []) 31 | for sock in read_list: 32 | if sock == s: 33 | data = sock.recv(4096) 34 | if not data : 35 | print ('\nDisconnected from chat server') 36 | sys.exit() 37 | else : 38 | sys.stdout.write(data.decode()+"\n") 39 | prompt() 40 | else : 41 | msg = sys.stdin.readline() 42 | s.send(msg.encode()) 43 | prompt() 44 | -------------------------------------------------------------------------------- /testWidgets.py: -------------------------------------------------------------------------------- 1 | from PyQt5.QtWidgets import * 2 | from PyQt5.QtGui import * 3 | from PyQt5.QtCore import * 4 | import sys,math 5 | 6 | class myDial(QDial): 7 | def __init__(self,parent=None,w=50,h=50): 8 | QDial.__init__(self,parent) 9 | self.setFixedSize(w+2,h+2) 10 | self.w=w 11 | self.h=h 12 | 13 | self.body=w*5/50 14 | self.cp=(w/2+1,h/2+1) 15 | self.d=w/5 16 | self.timer=QTimer(self) 17 | self.timer.timeout.connect(self.update) 18 | self.count=0 19 | self.timer.start(100) 20 | def setColor(self,qp,point): 21 | head,middle,little,tail=0,0,0,0 22 | head=point 23 | middle=head+1 24 | little=middle+1 25 | tail=little+1 26 | 27 | if point==9: 28 | tail=0 29 | elif point==10: 30 | little,tail=0,1 31 | elif point==11: 32 | middle,little,tail=0,1,2 33 | if self.count==head: 34 | qp.setPen(QPen(QColor("#686868"), self.body, Qt.SolidLine, Qt.RoundCap)) 35 | elif self.count==middle: 36 | qp.setPen(QPen(QColor("#888888"), self.body, Qt.SolidLine, Qt.RoundCap)) 37 | elif self.count==little: 38 | qp.setPen(QPen(QColor("#a8a8a8"), self.body, Qt.SolidLine, Qt.RoundCap)) 39 | elif self.count==tail: 40 | qp.setPen(QPen(QColor("#c8c8c8"), self.body, Qt.SolidLine, Qt.RoundCap)) 41 | else: 42 | qp.setPen(QPen(QColor("#d8d8d8"), self.body, Qt.SolidLine, Qt.RoundCap)) 43 | 44 | 45 | def paintEvent(self,e): 46 | qp=QPainter() 47 | qp.begin(self) 48 | qp.setPen(QPen(QColor("#a8a8a8"), self.body, Qt.SolidLine, Qt.RoundCap)) 49 | qp.setBrush(QColor("#c8c8c8")) 50 | #qp.drawEllipse(QRectF(1, 1, self.w, self.h)) 51 | 52 | #12点 53 | self.setColor(qp,0) 54 | qp.drawLine(self.cp[0], self.cp[1]-self.h*3/8, self.cp[0], self.cp[1]-self.h/4) 55 | 56 | self.setColor(qp,1) 57 | qp.drawLine(self.cp[0]+0.5*self.h*3/8, self.cp[1]-math.sqrt(3)*0.5*self.h*3/8, self.cp[0]+self.h/4*0.5, self.cp[1]-math.sqrt(3)*0.5*self.h/4) 58 | 59 | 60 | self.setColor(qp,2) 61 | qp.drawLine(math.sqrt(3)/2*(self.w*3/8)+self.cp[0], self.cp[1]-0.5*(self.w*3/8), math.sqrt(3)/2*(self.w/4)+self.cp[0],self.cp[1]-0.5*(self.w/4)) 62 | 63 | #3点 64 | self.setColor(qp,3) 65 | qp.drawLine(self.cp[0]+self.w*3/8, self.cp[1], self.cp[0]+self.w/4, self.cp[1]) 66 | 67 | 68 | 69 | self.setColor(qp,4) 70 | qp.drawLine(math.sqrt(3)/2*(self.w*3/8)+self.cp[0], self.cp[1]+0.5*(self.w*3/8), math.sqrt(3)/2*(self.w/4)+self.cp[0],self.cp[1]+0.5*(self.w/4)) 71 | 72 | self.setColor(qp,5) 73 | qp.drawLine(self.cp[0]+0.5*self.h*3/8, self.cp[1]+math.sqrt(3)*0.5*self.h*3/8, self.cp[0]+self.h/4*0.5, self.cp[1]+math.sqrt(3)*0.5*self.h/4) 74 | 75 | #6点 76 | self.setColor(qp,6) 77 | qp.drawLine(self.cp[0], self.cp[1]+self.h*3/8, self.cp[0], self.cp[1]+self.h/4) 78 | 79 | 80 | self.setColor(qp,7) 81 | qp.drawLine(self.cp[0]-0.5*self.h*3/8, self.cp[1]+math.sqrt(3)*0.5*self.h*3/8, self.cp[0]-self.h/4*0.5, self.cp[1]+math.sqrt(3)*0.5*self.h/4) 82 | self.setColor(qp,8) 83 | qp.drawLine(self.cp[0]-math.sqrt(3)/2*(self.w*3/8), self.cp[1]+0.5*(self.w*3/8),self.cp[0]- math.sqrt(3)/2*(self.w/4),self.cp[1]+0.5*(self.w/4)) 84 | 85 | #9点 86 | self.setColor(qp,9) 87 | qp.drawLine(self.cp[0]-self.w*3/8, self.cp[1], self.cp[0]-self.w/4, self.cp[1]) 88 | 89 | self.setColor(qp,10) 90 | qp.drawLine(self.cp[0]-math.sqrt(3)/2*(self.w*3/8), self.cp[1]-0.5*(self.w*3/8),self.cp[0]- math.sqrt(3)/2*(self.w/4),self.cp[1]-0.5*(self.w/4)) 91 | 92 | 93 | 94 | self.setColor(qp,11) 95 | qp.drawLine(self.cp[0]-0.5*self.h*3/8, self.cp[1]-math.sqrt(3)*0.5*self.h*3/8, self.cp[0]-self.h/4*0.5, self.cp[1]-math.sqrt(3)*0.5*self.h/4) 96 | qp.end() 97 | self.count+=1 98 | if self.count==12: 99 | self.count=0 100 | 101 | 102 | 103 | class MyWidget(QMainWindow): 104 | def __init__(self): 105 | QWidget.__init__(self) 106 | spin=myDial(self) 107 | self.setCentralWidget(spin) 108 | 109 | if __name__=="__main__": 110 | app=QApplication(sys.argv) 111 | myWidget=MyWidget() 112 | myWidget.show() 113 | app.exec_() 114 | -------------------------------------------------------------------------------- /qtclient.py: -------------------------------------------------------------------------------- 1 | """ 2 | 聊天室客户端程序代码 3 | """ 4 | import sys 5 | from PyQt5.QtWidgets import * 6 | from PyQt5.QtCore import * 7 | from PyQt5.QtNetwork import * 8 | from PyQt5.QtGui import QFont,QColor,QPainter,QPolygonF,QIcon,QCursor 9 | from math import * 10 | from customWidget import BubbleText,MsgList 11 | 12 | class LoginWindow(QMainWindow): 13 | """ 14 | 聊天室的登录窗口: 15 | """ 16 | def __init__(self, *args, **kwargs): 17 | super().__init__(*args, **kwargs) 18 | #usernameLabel=QLabel("用户名:") 19 | #passwdLabel=QLabel("用户名:") 20 | #self.label=QTex 21 | self.label=QLabel("

544 ChatRoom

") 22 | #self.label=BubbleText("

544 ChatRoom

") 23 | #self.label=BubbleText() 24 | self.label.setDisabled(True) 25 | self.setWindowFlags(Qt.FramelessWindowHint) 26 | self.username = QLineEdit() 27 | self.username.setPlaceholderText("username") 28 | self.password = QLineEdit() 29 | self.password.setPlaceholderText("password") 30 | self.password.setEchoMode(2) 31 | layout = QGridLayout() 32 | self.btnSend = QPushButton("login") 33 | self.btnQuit = QPushButton("quit") 34 | self.btnSend.pressed.connect(self.onBtnSend) 35 | self.btnQuit.pressed.connect(self.close) 36 | 37 | layout.addWidget(self.label, 0, 0, 1, 2) 38 | layout.addWidget(self.username, 1, 0, 2, 2) 39 | 40 | layout.addWidget(self.password, 3, 0, 2, 2) 41 | layout.addWidget(self.btnSend, 5, 0) 42 | layout.addWidget(self.btnQuit, 5, 1) 43 | widget = QWidget() 44 | widget.setLayout(layout) 45 | self.setCentralWidget(widget) 46 | self.btnSend.setStyleSheet("QPushButton:pressed{color:black;\ 47 | background-color:rgb(210,255,240);}") 48 | self.btnQuit.setStyleSheet("QPushButton:pressed{color:black;\ 49 | background-color:rgb(210,255,240);}") 50 | self.username.setStyleSheet("QLineEdit:focus{border:1px solid #aaaaf0}") 51 | self.password.setStyleSheet("QLineEdit:focus{border:1px solid #aaaaf0}") 52 | self.setStyleSheet("color:rgb(210,225,240);background-color:black") 53 | #self.resize(450,250) 54 | self.setFixedSize(320, 150) 55 | self.center() 56 | self.setWindowOpacity(0.95) 57 | 58 | def mousePressEvent(self, event): 59 | print(event.globalPos()) 60 | self.windowPos=self.pos() 61 | self.mousePos=event.globalPos() 62 | self.dPos=self.mousePos-self.windowPos 63 | 64 | def mouseMoveEvent(self, event): 65 | print(event.globalPos()) 66 | self.move(event.globalPos()-self.dPos) 67 | 68 | def center(self): 69 | """ 70 | center the window 71 | """ 72 | qr_ = self.frameGeometry() 73 | cp_ = QDesktopWidget().availableGeometry().center() 74 | qr_.moveCenter(cp_) 75 | self.move(qr_.topLeft()) 76 | 77 | def onBtnSend(self): 78 | """ 79 | 触发 80 | """ 81 | self.loginDialog = LoginDialog() 82 | self.loginDialog.connect() 83 | 84 | def keyPressEvent(self, QKeyEvent): 85 | """ 86 | 登录对话框的按键处理函数:按下回车键或者小键盘的enter键触发点击login按钮。 87 | """ 88 | if QKeyEvent.key() == Qt.Key_Return or QKeyEvent.key() == Qt.Key_Enter: 89 | self.btnSend.animateClick() 90 | if QKeyEvent.key() == Qt.Key_Escape: 91 | self.btnQuit.animateClick() 92 | 93 | 94 | class LoginDialog(QDialog): 95 | """ 96 | 登录对话框,调用不显示窗口,处理登录数据,成功则显示聊天室窗口,不成功则不显示聊天室窗口 97 | """ 98 | close_signal = pyqtSignal() 99 | 100 | def __init__(self, parent=None): 101 | QDialog.__init__(self, parent) 102 | self.sock = QTcpSocket() 103 | print("init successfully!") 104 | 105 | def connect(self): 106 | """ 107 | socket连接函数 108 | """ 109 | self.sock.connectToHost("localhost", 5000) 110 | #if not self.sock.isWritable(): 111 | loginmessage = "login:1,username:" + loginWindow.username.text() + ",password:" + loginWindow.password.text() 112 | print(loginmessage) 113 | if self.sock.isWritable(): 114 | self.sock.write(loginmessage.encode()) 115 | self.sock.readyRead.connect(self.slotreadyread) 116 | else: 117 | QMessageBox.warning(loginWindow, "Tips:", "Service Down", QMessageBox.Cancel) 118 | 119 | def slotreadyread(self): 120 | """ 121 | 收到服务器发来的数据处理 122 | """ 123 | if self.sock.bytesAvailable() > 0: 124 | data = bytes(self.sock.readLine()).decode().rstrip() 125 | print("dialog recv"+data) 126 | try: 127 | head,junk,tail = data.partition(":") 128 | finally: 129 | print(data) 130 | print("invalid data!") 131 | if head == "system" and tail=="login": 132 | data = bytes(self.sock.readLine()).decode().rstrip() 133 | try: 134 | head,junk,tail = data.partition(":") 135 | finally: 136 | print(data) 137 | print("invalid data!") 138 | if head=="success": 139 | chatWindow.show() 140 | chatWindow.getSocket(self.sock) 141 | self.sock.readyRead.disconnect(self.slotreadyread) 142 | del self.sock 143 | loginWindow.close() 144 | print("Login Successfully!") 145 | self.close() 146 | else: 147 | QMessageBox.warning(loginWindow,"Warning","Username or Password invalid!",QMessageBox.Cancel) 148 | 149 | 150 | def send(self, data, type_): 151 | """ 152 | 发送数据函数 153 | """ 154 | if type_ == "data": 155 | pass 156 | elif type_ == "message": 157 | if self.sock.isWritable(): 158 | self.sock.write(type_.encode()+":".encode()+data.encode()) 159 | 160 | 161 | class ChatWindow(QMainWindow): 162 | """ 163 | 聊天室主体窗口:有两个QTextBrowser控件,分别实现系统和用户聊天信息显示\ 164 | ,一个QLineEdit控件用于获取用户输入,一个QPushButton控件用于处理用户发送消息 165 | """ 166 | def __init__(self, *args, **kwargs): 167 | super(ChatWindow, self).__init__(*args, **kwargs) 168 | self.setWindowTitle("ChatRoom") 169 | self.view = QTextBrowser(self) 170 | self.chat = MsgList() 171 | self.content = QLineEdit() 172 | self.btnsend = QPushButton("send") 173 | layout = QGridLayout() 174 | layout.setContentsMargins(10, 10, 10, 10) 175 | layout.addWidget(self.view, 0, 0, 4, 3) 176 | layout.addWidget(self.chat, 0, 3, 3, 5) 177 | layout.addWidget(self.content, 3, 3, 1, 4) 178 | layout.addWidget(self.btnsend, 3, 7) 179 | widget = QWidget() 180 | widget.setLayout(layout) 181 | self.setCentralWidget(widget) 182 | self.center() 183 | self.setStyleSheet("ChatWindow{background-color:black}") 184 | self.setFixedSize(680, 480) 185 | self.content.setFocus(Qt.ActiveWindowFocusReason) 186 | 187 | def getSocket(self,socket): 188 | """从登录框中获取socket""" 189 | self.sock=socket 190 | self.sock.readyRead.connect(self.slotreadyread) 191 | def slotreadyread(self): 192 | """接受socket数据处理函数""" 193 | if self.sock.bytesAvailable() > 0: 194 | data = bytes(self.sock.readLine()).decode().rstrip() 195 | print("chat room recv:"+data) 196 | pass 197 | head,junk,tail = data.partition(":") 198 | if head=="system" and tail == "message": 199 | data = bytes(self.sock.readLine()).decode().rstrip() 200 | print("hello from "+data) 201 | head,junk,tail = data.partition(":") 202 | 203 | elif head=="system" and tail == "broadcast": 204 | data = bytes(self.sock.readLine()).decode().rstrip() 205 | print("hello from "+data) 206 | head,junk,tail = data.partition(":") 207 | if head in ("login","logout"): 208 | self.view.append(data) 209 | else: 210 | self.chat.addTextMsg(tail,True) 211 | print("head===%s"%head) 212 | 213 | def center(self): 214 | """"窗口中心化""" 215 | qr_ = self.frameGeometry() 216 | cp_ = QDesktopWidget().availableGeometry().center() 217 | qr_.moveCenter(cp_) 218 | self.move(qr_.topLeft()) 219 | 220 | def handle_click(self): 221 | """ 222 | 处理点击事件函数 223 | """ 224 | if not self.isVisible(): 225 | self.show() 226 | else: 227 | QMessageBox.warning(self, "Tips:", "Service Down", QMessageBox.Cancel) 228 | self.close() 229 | 230 | def handle_close(self): 231 | """关闭函数:""" 232 | self.close() 233 | 234 | def keyPressEvent(self, QKeyEvent): 235 | """按键处理函数:""" 236 | if QKeyEvent.key() == Qt.Key_Return or QKeyEvent.key() == Qt.Key_Enter: 237 | if self.content.hasFocus(): 238 | self.sock.write("message:".encode()+self.content.text().encode()) 239 | buble=BubbleText(self.content.text(),False) 240 | data=self.content.text() 241 | self.content.clear() 242 | self.chat.addTextMsg(data,False) 243 | 244 | def closeEvent(self,e): 245 | self.sock.write("logout:1".encode()) 246 | e.accept() 247 | 248 | class TestWindow(QMainWindow): 249 | """ 250 | 测试用的窗口 251 | """ 252 | def __init__(self, *args, **kwargs): 253 | super(TestWindow, self).__init__(*args, **kwargs) 254 | self.setWindowTitle("listWidget") 255 | listWidget=QListWidget() 256 | bubble=BubbleText("hello") 257 | item_=QListWidgetItem(bubble,"icon",listWidget) 258 | listWidget.insertItem(1,item_) 259 | layout=QHBoxLayout() 260 | layout.addWidget(listWidget) 261 | widget=QWidget() 262 | widget.setLayout(layout) 263 | self.setCentralWidget(widget) 264 | 265 | 266 | if __name__ == "__main__": 267 | app = QApplication(sys.argv) 268 | loginWindow = LoginWindow() 269 | chatWindow = ChatWindow() 270 | 271 | #loginWindow.btnSend.clicked.connect(chatWindow.handle_click) 272 | #loginWindow.btnSend.clicked.connect(loginWindow.close) 273 | 274 | loginWindow.show() 275 | #test=TestWindow() 276 | #test.show() 277 | app.exec_() -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | import socket,select 2 | import time,hashlib,random,sys,struct,os 3 | import redis,pymysql 4 | import redis 5 | import signal 6 | red="\033[0;31m" 7 | green="\033[0;32m" 8 | none="\033[0m" 9 | def handler(signal_num,frame): 10 | print("service stopping!") 11 | sys.exit(signal_num) 12 | signal.signal(signal.SIGINT,handler) 13 | class Table_ctrl(): 14 | def __init__(self,tablename): 15 | self.tablename=tablename 16 | self.connect_db() 17 | def connect_db(self): 18 | try: 19 | self.conn=pymysql.connect(user="jin",password="123456",database="CHATROOM",charset="utf8") 20 | except: 21 | os.system("service mysql start") 22 | self.conn=pymysql.connect(user="jin",password="123456",database="CHATROOM",charset="utf8") 23 | finally: 24 | self.cur=self.conn.cursor() 25 | def get_timeId(self): 26 | now=time.time() 27 | intnow=int(now) 28 | ms=int((now-intnow)*1000) 29 | timeId=time.strftime("%y%m%d%H%M%S",time.localtime(time.time()))+str(ms) 30 | return timeId 31 | def write_db(self,*data): 32 | sql="INSERT INTO "+str(self.tablename)+" VALUES('"+self.get_timeId()+"'" 33 | for i in range(len(data)): 34 | if type(data[i])==type("string"): 35 | sql+=",'"+data[i]+"'" 36 | else: 37 | sql+=","+str(data[i]) 38 | sql+=")" 39 | try: 40 | self.cur.execute(sql.encode('utf-8')) 41 | self.conn.commit() 42 | except Exception as e: 43 | print("writting database error:%s"%e) 44 | def checkExist(self,column,value): 45 | Exist=False 46 | if type(value)==type("string"): 47 | sql="select * from "+str(self.tablename)+" where "+str(column)+"='"+str(value)+"'" 48 | else: 49 | sql="select * from "+str(self.tablename)+" where "+str(column)+"="+str(value) 50 | try: 51 | self.cur.execute(sql) 52 | if self.cur.fetchone(): 53 | Exist=True 54 | except: 55 | print("check value Error!") 56 | return Exist 57 | def query_db(self,kColumn,kValue,queryField): 58 | if type(kValue)==type("string"): 59 | sql="select %s from %s where %s='%s'"%(queryField,self.tablename,kColumn,kValue) 60 | else: 61 | sql="select %s from %s where %s=%s"%(queryField,self.tablename,kColumn,kValue) 62 | print(sql) 63 | try: 64 | self.cur.execute(sql) 65 | return self.cur.fetchone()[0] 66 | except: 67 | print("query Error!") 68 | def __del__(self): 69 | self.conn.close() 70 | class Login(Table_ctrl): 71 | def __init__(self,username,password): 72 | Table_ctrl.__init__(self,"USER") 73 | self.username=username 74 | self.password=password 75 | def login(self): 76 | sha1=hashlib.sha1() 77 | sha1.update(self.password.encode('utf-8')) 78 | self.password=sha1.hexdigest() 79 | return self.isLegal(self.username,self.password) 80 | def isLegal(self,username,password): 81 | sql="SELECT * FROM USER WHERE USERNAME='{0}' AND PASSWORD='{1}'".format(username,password) 82 | print(sql) 83 | self.cur.execute(sql) 84 | result=self.cur.fetchone() 85 | if result: 86 | self.niname=result[3] 87 | return True 88 | else: 89 | return False 90 | class Register(Table_ctrl): 91 | def __init__(self,username,password,niname): 92 | Table_ctrl.__init__(self,"USER") 93 | self.username=username 94 | self.password=password 95 | self.niname=niname 96 | self.age=0 97 | self.sex='N' 98 | self.picId='NULL' 99 | def register(self): 100 | sha1=hashlib.sha1() 101 | sha1.update(self.password.encode('utf-8')) 102 | self.password=sha1.hexdigest() 103 | return self.isLegal() 104 | def isLegal(self): 105 | if self.checkExist("USERNAME",self.username) or self.checkExist("NINAME",self.niname): 106 | return False 107 | self.write_db(self.username,self.password,self.niname,self.age,self.sex,self.picId) 108 | return True 109 | def offline(sock): 110 | if online.get(sock): 111 | del online[sock] 112 | if online_niname.get(sock): 113 | broadcast_data(sock,"system:broadcast\nlogout:[%s] is offline."%online_niname[sock]) 114 | print(green+"[%s] is offline" % online_niname[sock]+none) 115 | del online_niname[sock] 116 | print(red+"Client (%s,%s) disconnected." % sock.getpeername()+none) 117 | sock.close() 118 | CONNECTION_LIST.remove(sock) 119 | def broadcast_data (sock, message): 120 | global online 121 | for socket in CONNECTION_LIST: 122 | if socket != server_socket and socket != sock and socket!=sys.stdin and online.get(socket): 123 | try : 124 | if message: 125 | message+="\n" 126 | socket.send(message.encode()) 127 | except Exception as e: 128 | print("Error:%s"%e) 129 | socket.close() 130 | CONNECTION_LIST.remove(socket) 131 | def parse_data(socket,data): 132 | global online 133 | global online_niname 134 | global CONNECTION_LIST 135 | try: 136 | mes=data.split(":")[0] 137 | if mes=="data": 138 | if not online.get(socket): 139 | return "system:data\nfailed:loginFirst" 140 | elif mes=="register": 141 | datalist=data.split(",") 142 | username=datalist[1].split(":")[1] 143 | password=datalist[2].split(":")[1] 144 | niname=datalist[3].split(":")[1] 145 | register_user=Register(username,password,niname) 146 | if register_user.register(): 147 | return "system:register\nsuccess:"+niname 148 | else: 149 | return "system:register\nfailed:user or niname exist" 150 | elif mes=="login": 151 | if online.get(socket): 152 | return "system:login\nfailed:login repeat" 153 | datalist = data.split(",") 154 | username=datalist[1].split(":")[1] 155 | password=datalist[2].split(":")[1] 156 | login_user=Login(username,password) 157 | if login_user.login(): 158 | print("login successfully!") 159 | tc=Table_ctrl("USER") 160 | niname=tc.query_db("USERNAME",username,"NINAME") 161 | online[sock]=True 162 | if not niname: 163 | niname="NULL" 164 | online_niname[sock]=niname 165 | broadcast_data(sock,"system:broadcast\nlogin:[%s]entered room" %online_niname[sock]) 166 | return "system:login\nsuccess:%s"%niname 167 | else: 168 | del login_user 169 | return "system:login\nfailed:user not exist!" 170 | elif mes=="update": 171 | if not online.get(socket): 172 | return "system:update\nfailed:loginFirst" 173 | print("update!") 174 | elif mes=="query": 175 | if not online.get(socket): 176 | return "system:query\nfailed:loginFirst" 177 | sentence="" 178 | for i in CONNECTION_LIST: 179 | if online_niname.get(i): 180 | sentence+=","+online_niname.get(i) 181 | return "system:query\nsuccess:"+sentence 182 | elif mes=="message": 183 | if not online.get(socket): 184 | return "system:message\nfailed:loginFirst" 185 | broadcast_data(sock,"system:broadcast\n{0}:{1}".format(online_niname[sock],data.partition(":")[2])) 186 | print("{0}:{1}".format(online_niname[sock],data.partition(":")[2])) 187 | dataLength=len(data.partition(":")[2]) 188 | return "system:message\nsuccess:%s"%dataLength 189 | elif mes=="logout": 190 | if online.get(sock): 191 | return "system:logout\nFailed:you did not login" 192 | broadcast_data(sock,"system:broadcast\nlogout:{0} left the room.".format(online_niname[sock])) 193 | now=time.strftime("%y-%m-%d",time.localtime(time.time())) 194 | logout_flag=True 195 | return "system:logout\nsuccess:"+now 196 | else: 197 | return "system:unknown" 198 | except Exception as e: 199 | print(" parse data Error:%s"%e) 200 | return "system:unknown" 201 | if __name__ == "__main__": 202 | CONNECTION_LIST = [sys.stdin] 203 | RECV_BUFFER = 4096 204 | PORT = 5000 205 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 206 | server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 207 | server_socket.bind(("0.0.0.0", PORT)) 208 | server_socket.listen(10) 209 | online={} 210 | online_niname={} 211 | CONNECTION_LIST.append(server_socket) 212 | print(green+"Chat server started on port "+none + str(PORT)) 213 | running=True 214 | while running: 215 | read_sockets,write_sockets,error_sockets = select.select(CONNECTION_LIST,[],[]) 216 | for sock in read_sockets: 217 | if sock == server_socket: 218 | sockfd, addr = server_socket.accept() 219 | CONNECTION_LIST.append(sockfd) 220 | message=green+"Client (%s, %s) connected\t" % addr+none 221 | print(message) 222 | tc=Table_ctrl("RECORD") 223 | tc.write_db(message) 224 | elif sock==sys.stdin: 225 | junk=sys.stdin.readline() 226 | if junk=="exit": 227 | running=False 228 | else: 229 | broadcast_data(sock,"testing\n") 230 | else: 231 | try: 232 | data = sock.recv(RECV_BUFFER) 233 | logout_flag=False 234 | if data: 235 | redata=parse_data(sock,data.decode().rstrip())+"\n" 236 | sock.send(redata.encode()) 237 | if logout_flag: 238 | offline(sock) 239 | else: 240 | offline(sock) 241 | except Exception as e: 242 | offline(sock) 243 | server_socket.close() 244 | def service(conn,addr): 245 | while True: 246 | data=conn.recv(1024).decode().rstrip() 247 | if data: 248 | parse_data(data) 249 | else: 250 | offline(conn) 251 | -------------------------------------------------------------------------------- /customWidget.py: -------------------------------------------------------------------------------- 1 | import os,sys 2 | from PyQt5.QtCore import * 3 | from PyQt5.QtGui import * 4 | from PyQt5.QtWidgets import * 5 | from math import * 6 | from testWidgets import myDial 7 | 8 | 9 | DEFAULT_HEAD = 'icons/qq.png' 10 | DEFAULT_MSG = 'Hello is there anyone?' 11 | DEFAULT_IMG = 'icons/img.png' 12 | DEFAULT_MSG="Hello World,zai zhe ge shijie shang meiyou shei nenggou sheipan wo" 13 | 14 | def checkContainChinese(s):#判断是否为英文 15 | for ch in s: 16 | if u'\u4e00' <= ch <= u'\u9fff': 17 | return True 18 | return False 19 | 20 | def splitStringByLen(text,Len):#其中使用\n分割,因此原来的\n将会被替换,一个中文大致顶三个英文的宽度 21 | #reload(sys) #暂时用 22 | text = text.replace('\n','.') 23 | (myText, nLen) = ('',0) 24 | for s in text: 25 | myText += s 26 | nLen += 3 if checkContainChinese(s) else 1 27 | if nLen >= (Len - 1): 28 | myText += '\n' 29 | nLen = 0 30 | return myText 31 | 32 | class BubbleText(QLabel): 33 | """ 34 | 文字的显示 主要是控件的大小调节, 35 | 起初准备用QTextEdit后来发现实现起来很难控制大小和混动条! 36 | 只能舍弃次用QLabel继承实现了,关于控件的水平大小采用控制字符数量的方法(ヘ(_ _ヘ)), 37 | 考虑到一个中文字符的宽度大概是3倍英文字符因此出现了checkContainChinese和splitStringByLen函数 38 | (我也不记得哪儿抄来的方法了)。在输入调用super(BubbleText, self).__init__(myText) 39 | 前就把字符用\n分割好来显示""" 40 | border = 5 41 | trigon = 15 42 | lineLen = 60 #每行的文字数量 43 | 44 | minH = 2 * trigon + 2 * border 45 | minW = 2 * trigon + 2 * border 46 | 47 | def __init__(self,listItem,listView,text = DEFAULT_MSG,lr = True): 48 | self.listItem = listItem 49 | self.listView = listView 50 | self.text = text 51 | #字符串长度限制 52 | myText = splitStringByLen(text, self.lineLen) 53 | # 文字分割 54 | super(BubbleText, self).__init__(myText) 55 | self.setMinimumWidth(self.minW) 56 | self.setFont(QFont("Times",15,QFont.Normal)) 57 | #self.setStyleSheet("QLabel:hover{background-color:rgba(210,240,250,255);}") # 58 | #鼠标滑过的颜色设置,这样自定义的paintEvent绘图区域就被看穿了 59 | self.setState(False)#设置鼠标不进入状态,方便绘图区域的颜色更新 60 | self.lr = lr #标志绘制左还是右 61 | if self.lr: 62 | '''为了让实现显示的图片不会在super(BubbleImage, self).paintEvent(e)时和绘制的背景气泡冲突, 63 | 设置控件的setContentsMargins绘图范围保证图像的绘图区域。''' 64 | self.setContentsMargins(self.trigon*sqrt(3)/2 + 15,self.border + 10,self.border + 15,self.border + 10) 65 | else: 66 | self.setContentsMargins(self.border + 15,self.border + 10,self.trigon*sqrt(3)/2 + 15,self.border + 10) 67 | 68 | def paintEvent(self, e): 69 | size = self.size() 70 | qp = QPainter() 71 | qp.begin(self) 72 | if self.lr: 73 | self.leftBubble(qp,size.width(),size.height()) 74 | else: 75 | self.rightBubble(qp,size.width(),size.height()) 76 | qp.end() 77 | super(BubbleText, self).paintEvent(e) 78 | 79 | def leftBubble(self,qp, w, h): 80 | qp.setPen(self.colorLeftE)#设置画笔颜色,绘制的矩形边缘颜色 81 | qp.setBrush(self.colorLeftM)#设置红色的笔刷 82 | middle = h*(1-0.618) 83 | shifty = self.trigon/2 84 | shiftx = self.trigon*sqrt(3)/2 85 | rL = QRectF(shiftx,1,w-shiftx-self.border,h-3) 86 | #更改为圆角矩形 87 | pL=QPolygonF() 88 | pL.append(QPointF(0,middle)) #起始点 89 | pL.append(QPointF(shiftx, middle + shifty)) # 第二点 90 | pL.append(QPointF(shiftx, middle-shifty)) #第三点 91 | """ 92 | pL.append(QPointF(w - self.border, h - self.border)) #第四点 93 | pL.append(QPointF(w - self.border, self.border)) #第五点 94 | pL.append(QPointF(shiftx, self.border)) #第六点 95 | pL.append(QPointF(shiftx, middle - shifty)) #第七点 96 | """ 97 | qp.drawPolygon(pL) 98 | qp.drawRoundedRect(rL,10,10) 99 | qp.setPen(self.colorLeftM) 100 | #qp.setPen(QColor("#ff0000")) 101 | line=QLine(shiftx,middle+shifty,shiftx,middle-shifty) 102 | qp.drawLine(line) 103 | 104 | 105 | def rightBubble(self, qp, w, h): 106 | qp.setPen(self.colorRightE)#设置画笔颜色,绘制的矩形边缘颜色 107 | qp.setBrush(self.colorRightM)#设置红色的笔刷 108 | middle = h*(1-0.618) 109 | shifty = self.trigon/2 110 | shiftx = self.trigon*sqrt(3)/2 111 | rL = QRectF(self.border,1,w-shiftx-self.border,h-3) 112 | #更改为圆角矩形 113 | pL=QPolygonF() 114 | pL.append(QPointF(w,middle)) #起始点 115 | pL.append(QPointF(w-shiftx, middle + shifty)) # 第二点 116 | pL.append(QPointF(w-shiftx, middle - shifty)) #第三点 117 | """ 118 | pL.append(QPointF(w - self.border, h - self.border)) #第四点 119 | pL.append(QPointF(w - self.border, self.border)) #第五点 120 | pL.append(QPointF(shiftx, self.border)) #第六点 121 | pL.append(QPointF(shiftx, middle - shifty)) #第七点 122 | """ 123 | qp.drawPolygon(pL) 124 | qp.drawRoundedRect(rL,10,10) 125 | qp.setPen(self.colorRightM) 126 | #qp.setPen(QColor("#ff0000")) 127 | line=QLine(w-shiftx,middle+shifty,w-shiftx,middle-shifty) 128 | qp.drawLine(line) 129 | 130 | def setState(self,mouse): 131 | '''鼠标进入和鼠标出时需要显示不一样的效果,主要就是更新颜色变量,然后调用update更新重绘''' 132 | if mouse:#鼠标进入 133 | #self.colorLeftM = QColor("#eaeaea") 134 | self.colorLeftM = QColor("#eaeaea") 135 | self.colorLeftE = QColor("#D6D6D6") 136 | self.colorRightM = QColor("#8FD648") 137 | self.colorRightE = QColor("#85AF65") 138 | else: 139 | self.colorLeftM = QColor("#fafafa") 140 | self.colorLeftE = QColor("#D6D6D6") 141 | self.colorRightM = QColor("#9FE658") 142 | self.colorRightE = QColor("#85AF65") 143 | self.update() #更新界面,不用执行也可以更新,但是不实时 144 | 145 | def enterEvent(self,e): 146 | # print 'mouse entered' 147 | self.setState(True) 148 | def leaveEvent(self,e): 149 | # print 'mouse leaved' 150 | self.setState(False) 151 | 152 | def contextMenuEvent(self,e): 153 | ''' 右键菜单实现文本的复制和控件的删除''' 154 | editUser = QAction(QIcon('icons/copy.png'),u'复制',self)#第一个参数也可以给一个QIcon图标 155 | editUser.triggered.connect(self.copyText) 156 | delUser = QAction(QIcon('icons/delete.png'),u'删除',self) 157 | delUser.triggered.connect(self.delTextItem)#选中就会触发 158 | menu = QMenu() 159 | menu.addAction(editUser) 160 | #menu.addAction(delUser) 161 | menu.exec_(QCursor.pos())#全局位置比较好,使用e.pos()还得转换 162 | e.accept() #禁止弹出菜单事件传递到父控件中 163 | 164 | def copyText(self,b): 165 | # print 'msg copyed' 166 | cb = QApplication.clipboard() 167 | cb.setText(self.text) 168 | 169 | def delTextItem(self,b): 170 | # print 'msg deleted' 171 | self.listView.takeItem(self.listView.indexFromItem(self.listItem).row()) 172 | 173 | 174 | class TextItem(QWidget): 175 | '''显示文字的Widget内容,为了让消息可以删除增加listItem和list传递到文本控件''' 176 | def __init__(self, listItem, listView, text = DEFAULT_MSG, lr=True, head = DEFAULT_HEAD): 177 | super(TextItem,self).__init__() 178 | hbox = QHBoxLayout() 179 | text = BubbleText(listItem,listView,text,lr) 180 | head = LabelHead(head) 181 | head.setFixedSize(50,50) 182 | dial=myDial() 183 | if lr is not True: 184 | hbox.addSpacerItem(QSpacerItem(1,1,QSizePolicy.Expanding,QSizePolicy.Preferred)) 185 | hbox.addWidget(dial) 186 | hbox.addWidget(text) 187 | hbox.addWidget(head) 188 | else: 189 | hbox.addWidget(head) 190 | hbox.addWidget(text) 191 | hbox.addWidget(dial) 192 | hbox.addSpacerItem(QSpacerItem(1,1,QSizePolicy.Expanding,QSizePolicy.Preferred)) 193 | 194 | hbox.setContentsMargins(0,0,0,0) 195 | self.setLayout(hbox) 196 | self.setContentsMargins(0,0,0,0) 197 | 198 | class LabelHead(QLabel): 199 | '''LabelHead(QLabel) 类主要是为了展示用户头像''' 200 | def __init__(self,addr = DEFAULT_HEAD): 201 | super(LabelHead,self).__init__() 202 | self.setScaledContents(True) 203 | self.setReadOnly(True) 204 | self.setPicture(addr) 205 | 206 | def setReadOnly(self,b): 207 | self._readOnly = bool(b) 208 | 209 | def setPicture(self,addr): 210 | '''设置图像:继承至QLabel以便可以setPixmap设置图片''' 211 | self._picAddr = addr 212 | img = QPixmap(addr) 213 | self.setPixmap(img) 214 | return True 215 | 216 | def getPicture(self): 217 | return self._picAddr 218 | 219 | 220 | class MsgList(QListWidget): 221 | """消息消息列表的控件,支持增加文字消息和增加图片消息""" 222 | def __init__(self): 223 | super(MsgList, self).__init__() 224 | # 设置所有样式锁定 225 | #qssFile.open(QFile.ReadOnly|QFile.Text) 226 | #print(qssFile.read()) 227 | #self.setStyleSheet(qssFile.read()) 228 | 229 | def addTextMsg(self,sz = DEFAULT_MSG, lr = True, head = DEFAULT_HEAD): 230 | it = QListWidgetItem(self) 231 | wid = self.size().width() 232 | item = TextItem(it,self,sz,lr,head) #增加必须指定本list和本item用于删除item 233 | # item.setEnabled(False) #对象灰度显示,不能导致ITEM不可选 234 | it.setSizeHint(item.sizeHint()) 235 | it.setFlags(Qt.NoItemFlags)# 设置Item不可选择 236 | self.addItem(it) 237 | self.setItemWidget(it,item) 238 | #self.setCurrentItem(it) 239 | 240 | def addImageMsg(self,img = DEFAULT_IMG, lr = True, head = DEFAULT_HEAD): 241 | it = QListWidgetItem(self) 242 | wid = self.size().width() 243 | item = ImageItem(it,self,img,lr,head) #增加必须指定本list和本item用于删除item 244 | # item.setEnabled(False) #对象灰度显示,不能导致ITEM不可选 245 | it.setSizeHint(item.sizeHint()) 246 | it.setFlags(Qt.ItemIsEnabled)# 设置Item不可选择 247 | self.addItem(it) 248 | self.setItemWidget(it,item) 249 | self.setCurrentItem(it) 250 | 251 | 252 | 253 | if __name__=='__main__': 254 | app=QApplication(sys.argv) 255 | ml=MsgList() 256 | ml.setMinimumSize(500,500) 257 | ml.addTextMsg("Hello",True) 258 | ml.addTextMsg("World!",False) 259 | ml.addTextMsg(u"昨夜小楼又东风,春心泛秋意上心头,恰似故人远来载乡愁,今夜月稀掩朦胧,低声叹呢喃望星空,恰似回首终究一场梦,轻轻叹哀怨...",True) 260 | ml.addTextMsg(u"With a gentle look on her face, she paused and said,她脸上带着温柔的表情,稍稍停顿了一下,便开始讲话...",False) 261 | ml.addTextMsg(u"With a gentle look on her face, she paused and said,她脸上带着温柔的表情,稍稍停顿了一下,便开始讲话",False) 262 | ml.addTextMsg(u"With a gentle look on her face, she paused and said,她脸上带着温柔的表情,稍稍停顿了一下,便开始讲话",False) 263 | ml.addTextMsg(u"With a gentle look on her face, she paused and said,她脸上带着温柔的表情,稍稍停顿了一下,便开始讲话",False) 264 | ml.addTextMsg(u"With a gentle look on her face, she paused and said,她脸上带着温柔的表情,稍稍停顿了一下,便开始讲话",False) 265 | ml.find 266 | ml.show() 267 | 268 | app.exec_() -------------------------------------------------------------------------------- /mysql.sql: -------------------------------------------------------------------------------- 1 | -- MySQL dump 10.16 Distrib 10.1.23-MariaDB, for debian-linux-gnu (x86_64) 2 | -- 3 | -- Host: localhost Database: CHATROOM 4 | -- ------------------------------------------------------ 5 | -- Server version 10.1.23-MariaDB-8 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!40101 SET NAMES utf8 */; 11 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; 12 | /*!40103 SET TIME_ZONE='+00:00' */; 13 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 14 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 15 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 16 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 17 | 18 | -- 19 | -- Table structure for table `PIC` 20 | -- 21 | 22 | DROP TABLE IF EXISTS `PIC`; 23 | /*!40101 SET @saved_cs_client = @@character_set_client */; 24 | /*!40101 SET character_set_client = utf8 */; 25 | CREATE TABLE `PIC` ( 26 | `ID` varchar(15) NOT NULL, 27 | `CONTENT` mediumblob NOT NULL, 28 | PRIMARY KEY (`ID`) 29 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 30 | /*!40101 SET character_set_client = @saved_cs_client */; 31 | 32 | -- 33 | -- Dumping data for table `PIC` 34 | -- 35 | 36 | LOCK TABLES `PIC` WRITE; 37 | /*!40000 ALTER TABLE `PIC` DISABLE KEYS */; 38 | /*!40000 ALTER TABLE `PIC` ENABLE KEYS */; 39 | UNLOCK TABLES; 40 | 41 | -- 42 | -- Table structure for table `RECORD` 43 | -- 44 | 45 | DROP TABLE IF EXISTS `RECORD`; 46 | /*!40101 SET @saved_cs_client = @@character_set_client */; 47 | /*!40101 SET character_set_client = utf8 */; 48 | CREATE TABLE `RECORD` ( 49 | `ID` varchar(15) NOT NULL, 50 | `CONTENT` text NOT NULL, 51 | PRIMARY KEY (`ID`) 52 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 53 | /*!40101 SET character_set_client = @saved_cs_client */; 54 | 55 | -- 56 | -- Dumping data for table `RECORD` 57 | -- 58 | 59 | LOCK TABLES `RECORD` WRITE; 60 | /*!40000 ALTER TABLE `RECORD` DISABLE KEYS */; 61 | INSERT INTO `RECORD` VALUES ('170608170335162',''),('170608170335184',''),('170608170335193',''),('170608170335210',''),('170608170335228',''),('170608170335238',''),('170608170335256',''),('170608170335279',''),('170608170335288',''),('170608170335305',''),('170608170335322',''),('170608170335330',''),('170608170335347',''),('170608170335364',''),('170608170335382',''),('170608170335391',''),('170608170335411',''),('170608170335417',''),('170608170335425',''),('170608170335434',''),('170608170335443',''),('170608170335452',''),('170608170335461',''),('170608170335469',''),('170608170335478',''),('170608170335488',''),('170608170335496',''),('170608170335505',''),('170608170335522',''),('170608170335539',''),('170608170335548',''),('170608170335564',''),('170608170335581',''),('170608170335590',''),('170608170335607',''),('170608170335624',''),('170608170335634',''),('170608170335651',''),('170608170335654',''),('170608170335671',''),('170608170335680',''),('170608170335696',''),('170608170335713',''),('170608170335731',''),('170608170335739',''),('170608170335756',''),('170608170335775',''),('170608170335782',''),('170608170335799',''),('170608170335816',''),('170608170335825',''),('170608170335842',''),('170608170335859',''),('170608170335867',''),('170608170335886',''),('170608170335893',''),('170608170335902',''),('170608170335910',''),('170608170335919',''),('170608170335929',''),('170608170335938',''),('170608170335947',''),('170608170335955',''),('170608170335964',''),('170608170335973',''),('170608170335982',''),('170608170335999',''),('170608170336101',''),('170608170336110',''),('170608170336127',''),('170608170336143',''),('170608170336152',''),('17060817033616',''),('170608170336169',''),('170608170336186',''),('170608170336203',''),('170608170336216',''),('170608170336232',''),('17060817033624',''),('170608170336241',''),('170608170336258',''),('170608170336276',''),('170608170336284',''),('170608170336301',''),('170608170336318',''),('170608170336327',''),('170608170336344',''),('170608170336361',''),('170608170336372',''),('170608170336386',''),('170608170336395',''),('170608170336404',''),('17060817033641',''),('170608170336413',''),('170608170336422',''),('170608170336430',''),('170608170336439',''),('170608170336448',''),('170608170336457',''),('170608170336466',''),('170608170336489',''),('170608170336497',''),('170608170336506',''),('170608170336523',''),('170608170336540',''),('170608170336548',''),('170608170336565',''),('17060817033658',''),('170608170336582',''),('170608170336591',''),('170608170336644',''),('170608170336646',''),('170608170336663',''),('17060817033667',''),('170608170336680',''),('170608170336697',''),('170608170336714',''),('170608170336730',''),('170608170336739',''),('170608170336756',''),('170608170336773',''),('170608170336782',''),('170608170336798',''),('170608170336815',''),('170608170336824',''),('17060817033684',''),('170608170336841',''),('170608170336858',''),('170608170336867',''),('170608170336883',''),('170608170336902',''),('170608170336909',''),('170608170336917',''),('170608170336927',''),('170608170336936',''),('170608170336945',''),('170608170336954',''),('170608170336963',''),('170608170336971',''),('170608170336980',''),('170608170336989',''),('170608170336998',''),('170608170337100',''),('170608170337116',''),('170608170337125',''),('170608170337142',''),('17060817033715',''),('170608170337159',''),('170608170337168',''),('170608170337185',''),('170608170337202',''),('170608170337212',''),('170608170337229',''),('170608170337246',''),('170608170337254',''),('170608170337271',''),('170608170337288',''),('170608170337296',''),('170608170337314',''),('17060817033732',''),('170608170337330',''),('170608170337339',''),('170608170337358',''),('170608170337366',''),('170608170337385',''),('170608170337393',''),('17060817033740',''),('170608170337400',''),('170608170337410',''),('170608170337418',''),('170608170337427',''),('170608170337436',''),('170608170337445',''),('170608170337453',''),('170608170337464',''),('170608170337473',''),('170608170337481',''),('170608170337498',''),('170608170337508',''),('170608170337525',''),('170608170337533',''),('170608170337550',''),('170608170337560',''),('17060817033757',''),('170608170337577',''),('170608170337584',''),('170608170337601',''),('170608170337631',''),('170608170337637',''),('170608170337654',''),('170608170337670',''),('170608170337679',''),('170608170337697',''),('170608170337705',''),('170608170337722',''),('17060817033774',''),('170608170337740',''),('170608170337748',''),('170608170337764',''),('170608170337774',''),('170608170337792',''),('170608170337799',''),('170608170337816',''),('170608170337826',''),('17060817033783',''),('170608170337843',''),('170608170337854',''),('170608170337861',''),('170608170337868',''),('170608170337878',''),('170608170337886',''),('170608170337895',''),('170608170337905',''),('170608170337914',''),('170608170337923',''),('170608170337931',''),('170608170337942',''),('170608170337950',''),('170608170337967',''),('170608170337977',''),('170608170337994',''),('1706081703381',''),('170608170338113',''),('170608170338130',''),('170608170338139',''),('170608170338156',''),('170608170338166',''),('17060817033818',''),('170608170338183',''),('170608170338194',''),('170608170338211',''),('170608170338217',''),('170608170338234',''),('170608170338245',''),('170608170338262',''),('170608170338269',''),('17060817033828',''),('170608170338286',''),('170608170338303',''),('170608170338316',''),('170608170338331',''),('170608170338338',''),('170608170338347',''),('170608170338356',''),('170608170338365',''),('170608170338373',''),('170608170338383',''),('170608170338392',''),('170608170338401',''),('170608170338412',''),('170608170338418',''),('170608170338436',''),('170608170338446',''),('17060817033846',''),('170608170338463',''),('170608170338471',''),('170608170338488',''),('170608170338505',''),('170608170338514',''),('17060817033853',''),('170608170338531',''),('170608170338548',''),('170608170338556',''),('170608170338573',''),('170608170338590',''),('170608170338601',''),('170608170338643',''),('170608170338648',''),('170608170338655',''),('170608170338672',''),('170608170338682',''),('170608170338699',''),('17060817033870',''),('170608170338715',''),('170608170338724',''),('170608170338740',''),('170608170338750',''),('170608170338767',''),('170608170338784',''),('170608170338793',''),('170608170338813',''),('170608170338817',''),('170608170338826',''),('17060817033887',''),('17060817033896',''),('170608170453716','Client (192.168.1.156, 43354) connected '),('170608170603927','Client (192.168.1.156, 42211) connected '),('170608170635244','Client (192.168.1.156, 57800) connected '),('170608170800243','Client (192.168.1.172, 27926) connected '),('17060817090028','Client (192.168.1.172, 27927) connected '),('170608171152135','Client (192.168.1.172, 27929) connected '),('170608171219817','Client (192.168.1.172, 27934) connected '),('170608171237625','Client (192.168.1.172, 27937) connected '),('170608171256393','Client (192.168.1.172, 27940) connected '),('170608171447236','Client (192.168.1.172, 27942) connected '),('170608171533567','Client (192.168.1.172, 27946) connected '),('170608172151908','Client (192.168.1.172, 27953) connected '),('17060817222790','Client (192.168.1.172, 27955) connected '),('170608175947748','Client (192.168.1.172, 28010) connected '),('170608180018330','Client (192.168.1.172, 28011) connected '); 62 | /*!40000 ALTER TABLE `RECORD` ENABLE KEYS */; 63 | UNLOCK TABLES; 64 | 65 | -- 66 | -- Table structure for table `USER` 67 | -- 68 | 69 | DROP TABLE IF EXISTS `USER`; 70 | /*!40101 SET @saved_cs_client = @@character_set_client */; 71 | /*!40101 SET character_set_client = utf8 */; 72 | CREATE TABLE `USER` ( 73 | `ID` varchar(15) NOT NULL, 74 | `USERNAME` varchar(20) NOT NULL, 75 | `PASSWORD` varchar(100) NOT NULL, 76 | `NINAME` varchar(20) NOT NULL, 77 | `AGE` tinyint(4) NOT NULL, 78 | `SEX` char(1) NOT NULL, 79 | `PIC` varchar(15) NOT NULL, 80 | PRIMARY KEY (`ID`), 81 | UNIQUE KEY `USERNAME` (`USERNAME`) 82 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 83 | /*!40101 SET character_set_client = @saved_cs_client */; 84 | 85 | -- 86 | -- Dumping data for table `USER` 87 | -- 88 | 89 | LOCK TABLES `USER` WRITE; 90 | /*!40000 ALTER TABLE `USER` DISABLE KEYS */; 91 | INSERT INTO `USER` VALUES ('111111111111111','jiu','7c4a8d09ca3762af61e59520943dc26494f8941b','JIUJIUJIU',0,'',''),('170608133221225','jin','7c4a8d09ca3762af61e59520943dc26494f8941b','Edward',0,'N','NULL'),('17060816101934','pillar','7c4a8d09ca3762af61e59520943dc26494f8941b','diaoliang',0,'N','NULL'),('222222222222222','ayi','7c4a8d09ca3762af61e59520943dc26494f8941b','AYI',0,'',''); 92 | /*!40000 ALTER TABLE `USER` ENABLE KEYS */; 93 | UNLOCK TABLES; 94 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; 95 | 96 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 97 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 98 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 99 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 100 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 101 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 102 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; 103 | 104 | -- Dump completed on 2017-06-08 18:06:42 105 | --------------------------------------------------------------------------------