Basic Python client socket example
It's trying to connect to the computer it's running on on port 5000, but the connection is being refused. Are you sure you have a server running?
If not, you can use netcat
for testing:
nc -l -k -p 5000
Some implementations may require you to omit the -p
flag.
A simple socket server and client program using python
Try changing to HOST, PORT = "0.0.0.0", 9999
in the server. Now the server should listen on all interfaces and not just the loopback interface. The same could also be achieved using an empty string i.e HOST, PORT = "", 9999
.
Simple two way socket communication
The server won't break out of its while
loop until the client either disconnects or at least shuts down the write half of its connection (with cs.shutdown(socket.SHUT_WR)
).
The client won't disconnect until it receives a message from the server, which the server sends outside of the while
loop (i.e. after the client disconnects/shuts down the write half of its connection).
You've created a deadlock.
Fundamentally, the issue is that it doesn't make sense to wait until the client has disconnected before you send a response to that client. Either the client needs to not expect a response back, or the server needs to send it while the client is still connected. In the case of the latter, you probably need to implement one of the following:
- The application protocol you're implementing needs a defined message structure so the server knows when the client has finished sending.
- The client needs a special sequence it can send to indicate the end of a message.
- The client needs to shut down the write half of its connection to indicate to the server that it won't send any more data.
Python simple socket client/server using asyncio
The closest literal translation of the threading code would create the socket as before, make it non-blocking, and use asyncio
low-level socket operations to implement the server. Here is an example, sticking to the more relevant server part (the client is single-threaded and likely fine as-is):
import asyncio, socket
async def handle_client(client):
loop = asyncio.get_event_loop()
request = None
while request != 'quit':
request = (await loop.sock_recv(client, 255)).decode('utf8')
response = str(eval(request)) + '\n'
await loop.sock_sendall(client, response.encode('utf8'))
client.close()
async def run_server():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 15555))
server.listen(8)
server.setblocking(False)
loop = asyncio.get_event_loop()
while True:
client, _ = await loop.sock_accept(server)
loop.create_task(handle_client(client))
asyncio.run(run_server())
The above works, but is not the intended way to use asyncio
. It is very low-level and therefore error-prone, requiring you to remember to set the appropriate flags on the socket. Also, there is no buffering, so something as simple as reading a line from the client becomes a tiresome chore. This API level is really only intended for implementors of alternative event loops, which would provide their implementation of sock_recv
, sock_sendall
, etc.
Asyncio's public API provides two abstraction layers intended for consumption: the older transport/protocol layer modeled after Twisted, and the newer streams layer. In new code, you almost certainly want to use the streams API, i.e. call asyncio.start_server
and avoid raw sockets. That significantly reduces the line count:
import asyncio, socket
async def handle_client(reader, writer):
request = None
while request != 'quit':
request = (await reader.read(255)).decode('utf8')
response = str(eval(request)) + '\n'
writer.write(response.encode('utf8'))
await writer.drain()
writer.close()
async def run_server():
server = await asyncio.start_server(handle_client, 'localhost', 15555)
async with server:
await server.serve_forever()
asyncio.run(run_server())
Related Topics
How to Run Python Script Without Typing 'Python ...'
Pandas Out of Bounds Nanosecond Timestamp After Offset Rollforward Plus Adding a Month Offset
How to Run an Ipython Magic from a Script (Or Timing a Python Script)
Update Tkinter Label from Variable
Use Python's String.Replace VS Re.Sub
Remove Adjacent Duplicate Elements from a List
Scrollbar on Matplotlib Showing Page
List Returned by Map Function Disappears After One Use
Is' Operator Behaves Differently When Comparing Strings with Spaces
"List Index Out of Range" When Using Sys.Argv[1]
Sum of List of Lists; Returns Sum List
Intercepting Stdout of a Subprocess While It Is Running
How to Change the Python Version in Visual Studio Code
Differencebetween Len() and Sys.Getsizeof() Methods in Python
How to Determine the Length of Lists in a Pandas Dataframe Column