HOWTO · Python
How to Fix OSError: [WinError 10038] an Operation Was Attempted on Something That Is Not a Socket
Learn how Python server and client sockets work, run a minimal example, and diagnose OSError: [WinError 10038] when code uses a socket after closing it.
On this page
OSError: [WinError 10038] means an operation was attempted on something that is not an active socket. In the faulty server pattern below, the accepted client socket is closed and then reused by an inner loop. Handle each connection once, then return to accept() for the next client.
Create a Minimal Python Client–Server Socket Example
A server listens for connections on a listening socket. When accept() returns, it gives the server a new connected socket for that client; the listening socket remains available for later connections. The client creates its own socket and calls connect() with the same address and port.
Save this as socket_demo.py. With no argument, it starts a server thread and a client for a compact local demonstration. The server and client modes also let you run the endpoints as separate processes.
import socket
import sys
import threading
HOST = "127.0.0.1"
PORT = 6060
MESSAGE = b"Welcome to the server!"
def serve(ready=None):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as listener:
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listener.bind((HOST, PORT))
listener.listen(1)
if ready is not None:
ready.set()
connection, address = listener.accept()
with connection:
print(f"Connected: {address[0]}")
connection.sendall(MESSAGE)
def receive():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as client:
client.connect((HOST, PORT))
chunks = []
while True:
chunk = client.recv(2048)
if not chunk:
break
chunks.append(chunk)
message = b"".join(chunks)
print(message.decode("utf-8"))
if len(sys.argv) > 1 and sys.argv[1] == "server":
serve()
elif len(sys.argv) > 1 and sys.argv[1] == "client":
receive()
else:
ready = threading.Event()
server = threading.Thread(target=serve, args=(ready,))
server.start()
ready.wait()
receive()
server.join()
Connected: 127.0.0.1
Welcome to the server!
The client collects data in chunks until the server closes the accepted connection, then combines the bytes before decoding them. This handles a message that arrives across multiple TCP reads. For separate processes, open two terminals in the directory containing the file. Run python socket_demo.py server in the first terminal; it waits for one client. Then run python socket_demo.py client in the second. The server prints the client’s loopback address, and the client prints the received message. The server closes that connection after sending, while its listening socket closes when this one-connection example ends.
Diagnose and Fix OSError: [WinError 10038]
In the faulty pattern, the outer loop calls accept() and stores the connected socket in Client_Socket. The inner while True sends once and closes that socket. On its next iteration, it tries to send on the same closed socket, which can raise OSError: [WinError 10038]. The inner loop does not call accept(); because it never exits, the outer loop cannot accept another client.
The repair is to remove the unconditional inner loop and handle one accepted connection per outer-loop iteration: accept, send, then close the connected socket. Keep the listening socket open while the server should accept more clients. Closing the accepted socket does not close the listening socket, and running the files from a terminal does not cause this error.
When diagnosing your own code, find the socket used by the failing operation, check whether that same socket was already closed, and confirm that each accepted connection is handled once. For a real service, keep the server’s accept loop running and place per-client work in a handler; this example intentionally serves one client and then exits.