用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

  

posted @ 2021-06-17 11:01  灰人  阅读(503)  评论(0)    收藏  举报