I created a server that displays data sent from a client. It worked initially but stopped after I tried to include SSL authentication. The issue seems to arise when I attempt to use the wrap_socket()
function.
import socket
import json
import ssl
HOST: str = '127.0.0.1'
PORT: int = 5507
def create_server_socket() -> socket.socket:
"""Creates a TCP socket, binds it to the host and port and listens for a connection. Will try again should the process fail"""
try:
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen()
print(f"SERVER LISTENING ON {HOST, PORT}")
return server_socket
except socket.error as message:
print("Socket creation error: " + str(message) + "\n Retrying...")
return create_server_socket()
def main() -> None:
"""Main function to start the server."""
context : ssl.SSLContext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain("ssl/server.crt", "ssl/server.key")
server_socket: socket.socket = create_server_socket()
context.wrap_socket(server_socket, server_side=True)
client_socket, client_address = server_socket.accept()
with client_socket:
data: bytes = client_socket.recv(1024)
print(f"{client_address} connected as {data.decode(encoding='utf-8')}\n")
while True:
data: bytes = client_socket.recv(1024)
decoded_data: str = data.decode(encoding='utf-8')
try:
data: dict =json.loads(decoded_data)
except json.JSONDecodeError:
print(f"{client_address} disconnected!")
server_socket.close()
client_socket.close()
break
print(f"{data['sender']}: {data['msg']}")
if __name__ == '__main__':
main()
I received the following error:
Traceback (most recent call last):
File "c:\Users\Yoocee\Desktop\Algorithmic Sciences\server.py", line 82, in <module>
main()
File "c:\Users\Yoocee\Desktop\Algorithmic Sciences\server.py", line 57, in main
client_socket, client_address = server_socket.accept()
^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Yoocee\AppData\Local\Programs\Python\Python311\Lib\socket.py", line 294, in accept
fd, addr = self._accept()
^^^^^^^^^^^^^^
OSError: [WinError 10038] An operation was attempted on something that is not a socket
What am I doing wrong and how do I fix it?
context.wrap_socket(server_socket, server_side=True)
client_socket, client_address = server_socket.accept()
According to the documentation wrap_socket
wraps "an existing Python socket sock and return an instance of SSLContext.sslsocket_class". You ignore the return value though. Instead you should do
server_socket = context.wrap_socket(server_socket, server_side=True)
client_socket, client_address = server_socket.accept()
That you should use the socket returned by wrap_socket
can also be seen from various examples in the documentation. So please use the documentation, it is pretty good.