Я установил связь клиент-сервер на python3. Он работает хорошо, сервер может обслуживать более одного клиента, все имеют openssl-import и используют многопоточность.
То, что я хочу сейчас: они должны иметь возможность использовать openSSL, и при получении чего-либо на сокете (сервер И клиент) они должны иметь возможность отправлять что-то, ПОЛУЧАЯ получение данных (например, вызов «count» от клиентаи после этого наберите что-нибудь еще при получении ответа). Но когда я запускаю свой код, каждый раз (при получении на стороне клиента), когда я хочу отправить что-либо, он в конце концов распознает то, что я пытался отправить. Трудно объяснить (мой английский не самый лучший). Что я делаю неправильно? Должен ли я сделать все сокеты в "неблокирующем режиме"? Может быть, вы можете проверить это:
сервер:
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::#
#:::::::::::::::::::::::::::::::::::: MULTITHREAD + SSL ::::::::::::::::::::::::::::::::::::::::::#
#::::::::::::::::::::::::::::::::::::::::::::: [ server.py ] ::::::::::::::::::::::::::::::::::::::::::::::::::#
#::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::#
#TODO: logs, try-exp
import socket as socketlib
import ssl
from threading import Thread
from time import ctime #formatiertes datetime nutzen!
import logging
import time
HOST = '127.0.0.1'
PORT = 4200
AUTHENTICATIONS = {'fin': 'finja',
'haxe': '1337',
'hell': 'd404559f602eab6fd602ac7680dacbfaadd13630335e951f097af3900e9de176b6db28512f2e000b9d04fba5133e8b1c6e8df59db3a8ab9d60be4b97cc9e81db'
}
logging.basicConfig(filename="log.log", level=logging.DEBUG,
format='[%(levelname)s] %(asctime)s - %(name)s : - LINE_%(lineno)s (%(funcName)s) # PROCESS ID %(process)s >>> THREAD ID %(thread)s\n || %(message)s \n')
def manage_client(connstream, client_socket, addr):
print("~~ Step 6/6 successful [Server started admitted request in new thread (Client {})] ~~".format(addr))
logging.debug("~~ Step 6/6 successful [Server started admitted request in new thread (Client %s)] ~~", addr)
connstream.sendall(b'Server accepted the connection!')
usr_accepted = False
while True:
data = connstream.recv(4096).decode("utf-8")
print("Client {}: ".format(addr), data)
logging.debug("Client %s: %s", addr, data)
if data == 'exit':
disconnect(connstream, addr)
break
elif data == "show status":
if usr_accepted:
show_status(connstream)
elif data == "username":
usr_accepted = authentication(connstream, addr)
if not usr_accepted:
disconnect(connstream, addr)
break
continue
elif data == "count":
for i in range(1, 10):
connstream.sendall(str(i).encode("utf-8"))
time.sleep(3)
try:
#connstream.sendall(b'Servertestmessage')
pass
except BrokenPipeError as e:
print(e)
logging.debug(e)
logging.exception('Got exception here')
print("MESSAGE COULD NOT BE SEND!")
logging.debug("MESSAGE COULD NOT BE SEND!")
connstream.close()
break
def authentication(connstream, addr):
usr_name = connstream.recv(4096).decode("utf-8")
usr_pwd = connstream.recv(4096).decode("utf-8")
if usr_name in AUTHENTICATIONS:
auth_pwd = AUTHENTICATIONS[usr_name]
if auth_pwd == usr_pwd:
connstream.send(b'Authentication succeeded!')
logging.debug("CLIENT AUTHENTICATION FROM {} ACCEPTED".format(addr))
return True
connstream.send(b'Authentication failed!')
logging.debug("CLIENT AUTHENTICATION FROM {} NOT ACCEPTED".format(addr))
return False
def disconnect(connstream, addr):
print("+++++ SOCKET CLOSED +++++ [Client {}]".format(addr))
logging.debug("+++++ SOCKET CLOSED +++++ [Client {}]".format(addr))
connstream.close()
def show_status(connstream):
server_location_time = ctime()
connstream.sendall(server_location_time.encode("utf-8"))
connstream.sendall("Location: CHINA".encode("utf-8"))
connstream.sendall("Adress: XYZ".encode("utf-8"))
connstream.sendall("Last update: Oct-11-2019".encode("utf-8"))
connstream.sendall("Python Version: 3".encode("utf-8"))
def main():
try:
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile="/home/fin/server.crt", keyfile="/home/fin/server.key")
print("~~ Step 1/6 successful [Loading ssl certification]~~")
logging.debug("~~ Step 1/6 successful [Loading ssl certification]~~")
except FileNotFoundError:
print("CERTIFICATE NOT FOUND!!")
logging.exception("Certificate could not be loaded. Program is not running anymore. Please restart the program!")
logging.error("Certificate could not be loaded. Program is not running anymore. Please restart the program!")
server_socket = socketlib.socket(socketlib.AF_INET, socketlib.SOCK_STREAM)
with server_socket:
server_socket.bind((HOST, PORT))
print("~~ Step 2/6 successful [Socket Binding IP {} on PORT {} as IPv4] ~~".format(HOST, PORT))
logging.debug("~~ Step 2/6 successful [Socket Binding IP {} on PORT {} as IPv4] ~~".format(HOST, PORT))
server_socket.listen()
print("~~ Step 3/6 successful [Server is listening for requests] ~~")
logging.debug("~~ Step 3/6 successful [Server is listening for requests] ~~")
try:
while True:
client_socket, addr = server_socket.accept()
print("~~ Step 4/6 successful [Server got a request from {}] ~~".format(addr))
logging.debug("~~ Step 4/6 successful [Server got a request from %s] ~~", addr)
client_socket = context.wrap_socket(client_socket, server_side=True)
print("~~ Step 5/6 successful [Request is ssl encrypted now (Client {})] ~~".format(addr))
logging.debug("~~ Step 5/6 successful [Request is ssl encrypted now (Client %s)] ~~", addr)
Thread(target=manage_client, args=(client_socket, server_socket, addr), daemon=True).start()
except KeyboardInterrupt as e:
print(e)
logging.exception(e)
if __name__ == "__main__":
main()
и клиент:
#::::::::::::::::::::::::::::::::::#
#:::: MULTITHREAD + SSL ::::#
#:::::::::: [ client.py] ::::::::::#
#::::::::::::::::::::::::::::::::::#
#TODO: logs
import socket, ssl, pprint, sys
from _thread import *
import time
import hashlib
#global msg
#msg = ''
IP = '127.0.0.1'
PORT = 4200
def msg_receive(conn, IP):
try:
while True:
msg = conn.recv(4096).decode("utf-8")
print("\n[{}]: {}".format(IP, msg))
time.sleep(0.000001)
if msg == '':
print("LOST CONNECTION TO SERVER!")
print("TRYING TO RECONNECT... (Refresh Browser!)") #TODO:
conn.close()
break
except OSError as e:
return
def msg_print_send(conn, IP):
while True:
message = input("\nNachricht: ")
conn.sendall(message.encode("utf-8"))
if message == 'username':
usr_message = input("\nBN: ")
conn.sendall(usr_message.encode("utf-8"))
pwd_message = hashlib.sha512(bytes(input("\nPW: "), "utf-8"))
p_message = (pwd_message.hexdigest())
conn.sendall(p_message.encode("utf-8"))
if message == 'exit':
print("+++++ SOCKET CLOSED +++++")
conn.close()
sys.exit() #TODO: skript beendet sich nicht
break
#if message != '':
#conn.sendall(message.encode("utf-8"))
#return
def main():
context = ssl.SSLContext()
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
try:
context.load_verify_locations("/home/fin/server.crt")
print("***CHECK- Certificate loading successful")
except (FileExistsError, FileNotFoundError) as e:
print(e)
print("::::: Program will be closed now! :::::")
sys.exit()
try:
# with socket.create_connection((ip, port)) as s:
conn = context.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), server_hostname="127.0.0.1")
print("***CHECK- Socket only supports ssl connection successful")
try:
conn.connect((IP, PORT))
print("***CHECK- Connection to server successful")
conn.sendall(b"Thanks for accepting the connection!")
print("***CHECK- Bytestring sending successful")
except:
print("CONNECTION NOT POSSIBLE! IN 10 SECONDS TRYING TO CONNECT AGAIN..")
time.sleep(10.0)
return
except ssl.CertificateError as e:
# print("Error {}: {}".format(e.args[0], e.args[1]))
# print("Error {}:".format(e)) #TODO: Darf Ziel-IP bekannt sein? (Fehlerprovokation bei Hackern) SICHERHEITSMANGEL!
print("Hostname doesn't match.")
print("::::: Program will be closed now! :::::")
sys.exit()
except ConnectionError as e:
# print("Error {}: {}".format(e.args[0], e.args[1]))
print(e)
print("::::: Program will be closed now! :::::")
sys.exit()
start_new_thread(msg_receive, (conn, IP))
start_new_thread(msg_print_send, (conn, IP))
try:
while 1:
#pass
time.sleep(1)
except KeyboardInterrupt as e:
print(e)
if __name__ == "__main__":
main()
Большое спасибо!