Исключение при попытке отправки и получения сообщений в сокете - PullRequest
0 голосов
/ 26 февраля 2020

Я пытаюсь создать чат для шифрования, использующий 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!')

1 Ответ

1 голос
/ 26 февраля 2020
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())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...