我正在尝试建立一个使用RSA作为加密算法的加密聊天,服务器正在等待一个客户端,然后在建立连接时,我尝试同时运行这两种方法。 (接收和发送消息)。
我的问题是,当我运行该程序时,出现错误,表明我认为该连接已关闭。我已经尝试解决这个问题很长时间了,但不知道为什么会发生。
错误:
客户端:尝试对非套接字的对象进行操作
服务器端:已建立的连接被主机中的软件中止了
服务器端:
import socket
from threading import Thread
from time import sleep
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
behavior = ['fuck', 'idiot', 'stupid', 'bitch', 'noob',
'butt', 'penis', 'jerk', 'vagina', 'asshole',
'dumbass', 'whorebag', 'nutsack', 'motherfucker',
'bitch', 'shit', 'whore', 'boner', 'dipshit',
'fuckoff', 'dipshit', 'lardass', 'pissed off',
'shitfaced', 'douchebag']
def main_text():
print("""
\t███╗ ██╗██╗ ██╗██╗ ██╗███████╗
\t████╗ ██║██║ ██║██║ ██╔╝██╔════╝
\t██╔██╗ ██║██║ ██║█████╔╝ █████╗
\t██║╚██╗██║██║ ██║██╔═██╗ ██╔══╝
\t██║ ╚████║╚██████╔╝██║ ██╗███████╗
\t╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
\tNuke - RSA Encrypted Chat | Roi Levi
""")
class EncryptedChat:
def __init__(self, username):
self.username = username.title()
self.key = RSA.generate(1024) # private_key
self.public_key = self.key.publickey() # pub_key
self.token_decryptor = PKCS1_OAEP.new(self.key)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as self.sock:
self.sock.bind(('0.0.0.0', 21513))
self.sock.listen(1)
print(f'\n\tHey, {self.username}. Waiting for Client: ')
self.conn, self.addr = self.sock.accept()
if self.conn:
print(f'\n\t{self.addr[0]}:{self.addr[1]} Has Connected to the party!\n')
Thread(target=self.send_msg).start()
Thread(target=self.recv_msg).start()
def send_msg(self) -> None:
ip_address = socket.gethostbyname(socket.gethostname())
while True:
user_message = input(f'\t{self.username}@{ip_address}: ').encode()
if user_message.decode().lower() in behavior:
print('\n\tDo not curse other people, Banned for 30 seconds!')
sleep(30)
else:
self.user_public_key = RSA.importKey(self.conn.recv(1024))
self.token = PKCS1_OAEP.new(self.user_public_key)
cipher_text = self.token.encrypt(user_message)
self.conn.send(cipher_text)
def recv_msg(self) -> None:
while True:
self.conn.send(self.public_key.exportKey())
cipher_msg = self.conn.recv(1024)
plain_text = self.token_decryptor.decrypt(cipher_msg)
print(f'\tRecveived: {plain_text.decode()}')
main_text()
your_username = input('\n\tEnter Username: ')
if your_username in behavior:
raise ValueError('\n\tInvalid Username, Do not use curse as username!')
else:
if __name__ == '__main__':
try:
EncryptedChat(your_username)
except KeyboardInterrupt:
print('\n\tThank you for using our software, Good Bye!')
客户端:
import socket
from time import sleep
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from threading import Thread
behavior = ['fuck', 'idiot', 'stupid', 'bitch', 'noob',
'butt', 'penis', 'jerk', 'vagina', 'asshole',
'dumbass', 'whorebag', 'nutsack', 'motherfucker',
'bitch', 'shit', 'whore', 'boner', 'dipshit',
'fuckoff', 'dipshit', 'lardass', 'pissed off',
'shitfaced', 'douchebag']
def main_text():
print("""
\t███╗ ██╗██╗ ██╗██╗ ██╗███████╗
\t████╗ ██║██║ ██║██║ ██╔╝██╔════╝
\t██╔██╗ ██║██║ ██║█████╔╝ █████╗
\t██║╚██╗██║██║ ██║██╔═██╗ ██╔══╝
\t██║ ╚████║╚██████╔╝██║ ██╗███████╗
\t╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
\tNuke - RSA Encrypted Chat | Roi Levi
""")
class Client:
def __init__(self, username):
self.username = username.title()
self.key = RSA.generate(1024)
self.public_key = self.key.publickey()
self.token_decryptor = PKCS1_OAEP.new(self.key)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as self.sock:
self.sock.connect((socket.gethostname(), 21513))
Thread(target=self.send_msg).start()
Thread(target=self.recv_msg).start()
def send_msg(self) -> None:
ip_address = socket.gethostbyname(socket.gethostname())
while True:
user_msg = input(f'\t{self.username}@{ip_address}: ').encode()
if user_msg.decode().lower() in behavior:
print('\n\tDo not curse other people, Banned for 30 minutes.')
sleep(30)
else:
self.user_public_key = RSA.importKey(self.sock.recv(1024))
self.token = PKCS1_OAEP.new(self.user_public_key)
cipher_text = self.token.encrypt(user_msg)
self.sock.send(cipher_text)
def recv_msg(self) -> None:
while True:
self.sock.send(self.public_key.export_key())
cipher_msg = self.sock.recv(1024)
plain_text = self.token_decryptor.decrypt(cipher_msg)
print(f'\tRecveived: {plain_text.decode()}')
main_text()
your_username = input('\n\tEnter Username: ')
if your_username in behavior:
raise ValueError('\tDo not use curse as your username!')
else:
if __name__ == '__main__':
try:
Client(your_username)
except KeyboardInterrupt:
print('\n\tThank you for using our software, Good Bye!')
答案 0 :(得分:1)
def __init__(self, username):
...
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as self.sock:
当您离开with ...
块时,套接字将立即获得,如以下示例所示:
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print("inside",s)
print("outside",s)
此结果
inside <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>
outside <socket.socket [closed] fd=-1, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0>
^^^^^^^^
如您所见,套接字在with ...
块外部关闭。因此,在self.sock
和send_msg
内对recv_msg
进行的任何操作都将失败,并显示“试图对不是套接字的对象进行操作” 。
因此,不要使用with ...
而是
def __init__(self, username):
...
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((self.sock.gethostname(), 21513))
...
除了在某些情况下您甚至没有使用self.sock
,而是错误地使用socket
。例如,在这种情况下:
def send_msg(self) -> None:
ip_address = socket.gethostbyname(socket.gethostname())