用python写一个加密通讯软件
这几天想着完成这个python的加密通讯软件,涉及到socket编程、加密技术以及一些python简易UI的使用方法,正好在这里做一个总结。
socket编程部分
很明显这个软件最重要的就是socket编程部分的代码,因为是第一版的所以只要我们完成了相应功能就可以了。但是很多地方我们仍然要使用清楚,搞明白到底是怎么用的。
服务器端
需要导入的包就只有socket和threading两个包。
之后我们要写两个函数,并使用线程来不断运行这两个函数
def clientThreadIn(conn,nick): global data while True: try: temp = conn.recv(1024) if not temp: conn.close() return NotifyAll(temp) print(data) except: NotifyAll(nick+'leaves the room') print(data) return
使用一个大循环不断去运行读取数据的逻辑,temp从接收的数据中读取1024个字节,然后执行一个NotifyALL函数把这个数据传进去。
def NotifyAll(ss): global data if con.acquire(): data = ss con.notifyAll() con.release()
这里Condition对象(这里的con)维护了一个锁(Lock/RLock)和一个waiting池。线程通过acquire获得Condition对象。这里,使用acquire好比声明我要执行下面的代码但是所有线程只能依次执行,我执行其他线程就需要等待。使用notifyAll则表示告诉其他线程可以抢夺这段资源的使用权了,但是此时我还没有把资源释放出去,需要最后执行release来把资源释放给其他线程进行执行。
在生产者-消费者模型中,生产者生产前使用acquire来进行生产声明,循环中每生产一个就release释放给其他的生产者,防止一次性生产太多,当货物到达max的时候,则使用notifyall来告诉其他线程可以再来制造了,并使用wait让自己处于等待,仍然也要使用release释放给其他的生产者。这样就能保证:我们一起制造货物,但是实际上我们不会同时生产货物而是按照顺序来的,生产到上限我们则都会进行等待,如果生产的货物被快速消耗掉了我们还会继续生产。
消费者模型则不需要,大家去抢夺资源就可以了。在产品被抢没了的时候,使用生产者中的函数通知生产者进行生产。通知的时候每个线程只通知一次所以也要使用acquire,通知完后也要释放掉。
服务器端的逻辑如下:
1.通过ip和端口号创建一个socket
2.开始监听
3.循环的接收socket接收到的信息
对比起来代码如下:
Host = input('input the ip adress') port = 1110 data = '' s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) print("socket created") s.bind((Host,port)) s.listen(5) print('Socket now listen')
while true部分的代码省略了,循环通过s.accept()获得一个conn,之后在线程里通过conn.recv来接受信息。
客户端
客户端设计了一个简单的ui,通讯方面仍然使用线程
self.sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) self.sock.connect((self.IP,self.port)) self.sock.send(self.nick.encode()) thin = threading.Thread(target = self.DealIn,args = (self.sock,)) thin.start()
socket.SOCK_STREAM是tcp的方式传输,然后使用connect主动连接到服务器端如果连接上了会返回一个值。
def DealOut(self,sock,mes):
self.outString = mes
self.outString = self.nick + ':'+self.outString
self.outString = self.outString.encode()
sock.send(self.outString)
#time.sleep(1)
def DealIn(self,sock):
while True:
try:
self.inString = sock.recv(1024)
self.inString = self.inString.decode()
if not self.inString:
break
if self.outString != self.inString:
print("接收信息",self.inString)
#---------聊天框显示信息----------#
self.st.config(state=NORMAL)
self.st.insert('end',self.inString)
self.st.insert('insert','\n')
self.st.config(state=DISABLED)
except:
break

浙公网安备 33010602011771号