1. socket的定义
socket又称套接字,应用程序通常通过‘套接字’向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。
2. 套接字的工作流程
3. socket函数使用
服务端实现:
import socket sk = socket.socket() #创建服务器套接字 ip_port = ('127.0.0.1',9999) sk.bind(ip_port) #套接字与地址绑定 sk.listen(5) #监听连接,传入连接请求的最大数 while True: conn,address = sk.accept() #返回一个元组,(socketobject,客户端ip和port) conn.send(('how are you').encode()) flag = True while flag: data = conn.recv(1024).decode() print(data) if data == 'exit': flag = False conn.send(('how are you').encode()) conn.close()
客户端实现:
import socket client = socket.socket() ip_port = ('127.0.0.1',9999) client.connect(ip_port) while True: data = client.recv(1024).decode() print(data) inp = input('client:') inp = client.send((inp).encode()) if inp == 'exit': break
4. tkinter+socket实现的小型聊天室
服务端实现
# -*-conding:utf-8 -*- from tkinter import * import os import socket import _thread import sys import datetime from mysql.connector import connect class mysqlhelper(object): def __init__(self): self.__conn_dic = dict(host='localhost',user='root',password='123456',port='3306',database='test') def getdic(self,sql,params): con = connect(**self.__conn_dic) cur = con.cursor() recount = cur.execute(sql,params) data = cur.fetchall() con.commit() con.close() return data def getone(self,sql,params): con = connect(**self.__conn_dic) cur = con.cursor() recount = cur.execute(sql,params) data = cur.fetchone() con.commit() con.close() return data def insertdata(self,sql,params): con = connect(**self.__conn_dic) cur = con.cursor() recount = cur.execute(sql,params) con.commit() con.close() def getall(self,sql): con = connect(**self.__conn_dic) cur = con.cursor() recount = cur.execute(sql) data = cur.fetchall() con.commit() con.close() return data class ServerUI(): title = 'Server ChatRoom' ip_port = ('127.0.0.1',9999) def __init__(self): #Server GUI self.__help = mysqlhelper() self.root = Tk() #生成root主窗体 self.root.title(self.title) #title self.frame = Frame(self.root) #生成frame self.frame.pack(fill=BOTH,padx=3,pady=3,expand=1) #将frame添加到root主窗体 self.leftFrame = Frame(self.frame) self.leftFrame.pack(side=LEFT,fill=BOTH,padx=3,pady=3) self.textDisplay = Text(self.leftFrame,height=20,width=40) self.textDisplay.pack(fill=X,expand=1,padx=3,pady=3) self.textInput = Text(self.leftFrame,height=10,width=40) self.textInput.pack(fill=X,expand=1,padx=3,pady=3) self.sendBtn = Button(self.leftFrame,text='发送',command=self.sendMessage) # self.sendBtn.bind('<Return>',self.sendMessage) self.sendBtn.pack(side=LEFT,padx=3,pady=3) self.downloadBtn = Button(self.leftFrame,text='上传/下载') self.downloadBtn.pack(side=LEFT,padx=20,pady=3) self.robotBtn = Button(self.leftFrame,text='小冰') self.robotBtn.pack(side=LEFT,padx=12,pady=3) self.rightFrame = Frame(self.frame) self.rightFrame.pack(side=RIGHT,fill=BOTH,pady=3) self.scrollbar = Scrollbar(self.rightFrame) self.scrollbar.pack(side=RIGHT,fill=Y) self.history = Listbox(self.rightFrame,yscrollcommand=self.scrollbar.set) # for line in range(100): # self.history.insert(END,"this is line number"+str(line)) self.history.pack(fill=Y,expand=1) self.scrollbar.config(command=self.history.yview) self.historyBtn = Button(self.rightFrame,text='历史纪录',command=self.historyMessage) self.historyBtn.pack(side=RIGHT) def receiveMessage(self): self.sk = socket.socket() self.sk.bind(self.ip_port) self.sk.listen(5) while True: self.conn,self.addr = self.sk.accept() self.conn.send(('How Are you').encode()) flag = True while flag: self.data = self.conn.recv(1024).decode() theTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') sql = 'insert into historytab (message,date) values (%s,%s)' params = (self.data,theTime,) self.__help.insertdata(sql,params) self.textDisplay.insert(END,'Client:'+ theTime + ' ') self.textDisplay.insert(END,self.data+' ') # self.conn.send(('How Are you').encode()) def sendMessage(self): message = self.textInput.get(1.0,END) theTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.textDisplay.insert(END,'Server:'+ theTime + ' ') self.textDisplay.insert(END,message+' ') self.conn.send((message).encode()) self.textInput.delete(1.0,END) def historyMessage(self): sql = 'select * from historytab' data = self.__help.getall(sql) for i in range(0,len(data)): self.history.insert(END,str(data[i])+' ') # self.history.insert(END,"this is line number"+str(line)) #使用线程接收客户端消息 def startNewThread(self): _thread.start_new_thread(self.receiveMessage,()) def main(): server = ServerUI() server.startNewThread() server.root.mainloop() if __name__ == '__main__': main()
客户端实现:
# -*-conding:utf-8 -*- from tkinter import * import os import socket import _thread import sys import datetime class ClientUI(): title = 'Client ChatRoom' ip_port = ('127.0.0.1',9999) def __init__(self): #Client GUI self.root = Tk() self.root.title(self.title) self.frame = Frame(self.root) self.frame.pack(fill=BOTH,padx=3,pady=3,expand=1) self.leftFrame = Frame(self.frame) self.leftFrame.pack(side=LEFT,fill=BOTH,padx=3,pady=3) self.textDisplay = Text(self.leftFrame,height=20,width=40)#yscrollcommand=self.scrollbar.set) # self.textDisplay.pack(fill=X,expand=1,padx=3,pady=3) self.textDisplay.pack(fill=BOTH,expand=1,padx=3,pady=3) # self.scrollbar = Scrollbar(self.textDisplay) # self.scrollbar.pack(side=RIGHT,fill=Y) # self.scrollbar.config(command=self.textDisplay.yview) # self.scrollbar = Scrollbar(self.leftFrame) self.textInput = Text(self.leftFrame,height=10,width=40) # self.textInput.pack(fill=X,expand=1,padx=3,pady=3) self.textInput.pack(fill=BOTH,expand=1,padx=3,pady=3) # self.scrollbar.config(command=self.textInput.yview) # self.scrollbar = Scrollbar(self.textInput) # self.scrollbar.pack(side=RIGHT,fill=Y) # self.scrollbar.config(command=self.textInput.yview) self.sendBtn = Button(self.leftFrame,text='发送',command=self.sendMessage) # self.sendBtn.bind('<Return>',self.sendMessage) self.sendBtn.pack(side=LEFT,padx=3,pady=3) self.downloadBtn = Button(self.leftFrame,text='上传/下载') self.downloadBtn.pack(side=LEFT,padx=20,pady=3) self.robotBtn = Button(self.leftFrame,text='小冰') self.robotBtn.pack(side=LEFT,padx=12,pady=3) self.rightFrame = Frame(self.frame) self.rightFrame.pack(side=RIGHT,fill=BOTH,pady=3) self.scrollbar = Scrollbar(self.rightFrame) self.scrollbar.pack(side=RIGHT,fill=Y) self.history = Listbox(self.rightFrame,yscrollcommand=self.scrollbar.set) # for line in range(100): # self.history.insert(END,"this is line number"+str(line)) self.history.pack(fill=Y,expand=1) self.scrollbar.config(command=self.history.yview) self.historyBtn = Button(self.rightFrame,text='历史纪录') self.historyBtn.pack(side=RIGHT) def receiveMessage(self): self.client = socket.socket() self.client.connect(self.ip_port) while True: self.data = self.client.recv(1024).decode() theTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.textDisplay.insert(END,'Server:'+ theTime + ' ') self.textDisplay.insert(END,self.data + ' ') def sendMessage(self): message = self.textInput.get(1.0,END) theTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') self.textDisplay.insert(END,'Client:'+ theTime + ' ') self.textDisplay.insert(END,message+' ') self.client.send((message).encode()) self.textInput.delete(1.0,END) #使用线程接收消息 def startNewThread(self): _thread.start_new_thread(self.receiveMessage,()) def main(): client = ClientUI() client.startNewThread() client.root.mainloop() if __name__ == '__main__': main()
实现效果: