I am writing a simple python proxy with Python 3.8 on Windows 10
If I use socket.accept I cannot terminate the process from console neither of these work: ctrl+c, ctrl+z, ctrl+d, break, ctrl+break, only closing the terminal.
I found in the docs this PIP https://www.python.org/dev/peps/pep-0475/ that is about retrying system calls on interrupts. I believe this is the reason why I cannot terminate the app.
Can anyone tell me a best practice how to terminate an app with a blocking socket.accept
Thanks in advance
my code:
import socket
bind_ip = "127.0.0.1"
bind_port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((bind_ip, bind_port))
server.listen(5)
print("[*] Listening on {}:{}".format(bind_ip, bind_port))
def handle_client(client_socket):
request = client_socket.recv(1024)
print("received: " + request.decode('ascii'))
client_socket.send("ACK".encode('ascii'))
client_socket.close()
while True:
client, addr = server.accept()
print("[*] accepted {}:{}".format(addr[0], addr[1]))
handle_client(client)
The socket might be in a TIME_WAIT state from the earlier trials & executions of your code.
You can use this flag to mitigate this, socket.SO_REUSEADDR
Under the Python Socket Documentation, you can set the flag like this.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
You can also look into setting a timeout for the socket!
Related
Using sockets, the below Python code opens a port and waits for a connection. Then, it sends a response when a connection is made.
import socket
ip = 127.0.0.1
port = 80
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ip, port))
s.listen(1)
conn, addr = s.accept()
conn.send(response)
conn.close()
If a connection is not established within 10 seconds, I would like it to move on. Is there a way to define a timeout for s.accept()?
s.accept(timeout=10)
Maybe something like the above line?
Thanks in advance for your help!
to set a timeout for socket s before you connect listen do s.settimeout(10)
edit
I assume it works when listening
Use socket.settimeout:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(10)
timeout = False
while not timeout:
try:
(conn, addr) = s.accept()
except socket.timeout:
pass
else:
# your code
To make a 10 second timeout the default behavior for any socket, you can use
socket.setdefaulttimeout(10)
I am creating a socket server in python
s= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind("127.0.0.1", 9001)
s.listen(5)
When a connect a Client using socket.connect() I am able to connect and close the client connection. But I am unable to close the server from ctrl+c or keyboard interrupt using s.shutdown(socket.SOL_RDWR)
Is there a way I can shutdown the python socket server using keyinterrupt or programmatically?
Update:
s= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.listen(5)
while True and s:
conn, addr = s.accept()
conn.recv(1024).decode()
conn.send("Test message from server".encode())
conn.close()
# Position 4 Signal Here
Update 2:
I did try to do this within the loop above in Position 4 "# Position 4 Signal Here". It did not work
import sys
import signal
def signal_handler(signal, frame):
sys.exit(1)
signal.signal(signal.SIGINT, signal_handler)
Update:
0$: This is windows 10 OS
I have a server which accepts a stream of JSON data from a client socket. The server needs to keep all the connections open forever and process the data that comes from them, but the current version of my code can handle a single connection only because the second while loop never ends once the first connection has been established.
import socket
IP = '127.0.0.1'
PORT = 1235
BUFFER = 10
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen(10)
print(f"Listening for incoming connections # {IP}:{PORT}")
while True:
client_socket, client_address = server_socket.accept()
print(f"Established connection with {client_address}")
while True:
received_message = client_socket.recv(BUFFER).decode('utf-8')
while '}' not in received_message:
received_message += client_socket.recv(BUFFER).decode('utf-8')
print(client_address, received_message)
client_socket.send("Message received".encode('utf-8'))
Was able to solve the problem by implementing threading. Here's the working code if anyone wants to use it.
import socket
from _thread import *
IP = '127.0.0.1'
PORT = 1235
BUFFER = 100
thread_count = 0
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((IP, PORT))
server_socket.listen(10)
def threaded_client(client_socket, address):
while True:
received_message = client_socket.recv(BUFFER).decode('utf-8')
while '}' not in received_message:
received_message += client_socket.recv(BUFFER).decode('utf-8')
print(client_address, received_message)
client_socket.send("Message received.".encode('utf-8'))
while True:
client_socket, client_address = server_socket.accept()
print(f"Established connection with {client_address}")
start_new_thread(threaded_client, (client_socket, client_address))
thread_count += 1
print(thread_count)
The primary problem you're facing is that almost all of python's IO is blocking. That means that the execution of the program stops when you want to read or write to a file, or to a socket in this case. The standard solution is to use threads through the threading-library, but there are many other options.
I'd recommend watching David Beazley's video on concurrency, which covers this topic quite well! It can get a little bit complicated, but that's because it's covering a lot of ground fairly quickly!
I am attempting to connect a simple server and client from two computers on the same network. Both the client and server cannot 'find' each other, as they do not move past .connect() and .accept() respectively. What am I doing wrong?
(Windows 10)
Server:
import socket
HOST = socket.gethostname() #Returns: "WASS104983"
#I have also tried socket.gethostbyname(socket.gethostname)), returning: "25.38.252.147"
PORT = 50007
sock = socket.socket()
sock.bind((HOST, PORT))
sock.listen(5)
print("Awaiting connection... ")
(clnt, addr) = sock.accept()
print("Client connected")
…
and Client:
import socket
HOST = "WASS104983" #Or "25.38.252.147", depending on the servers setup
PORT = 50007
sock = socket.socket()
print("Attempting connection... ")
sock.connect((HOST, PORT))
print("Connected")
…
I have gotten this to work before so I am not sure why it's not now.
I know there are a few questions of this calibre, but none seem to cover my problem.
Also, a wifi extender should not interfere with local transmissions should it?
I have always seen servers setup as such:
import socket
import threading
bind_ip = '0.0.0.0'
bind_port = 9999
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
print("[*] Listening on {}:{}".format(bind_ip, bind_port))
def handle_client(client_socket):
request = client_socket.recv(1024)
print('received: {}'.format(request))
client_socket.send(b'ACK!')
client_socket.close()
while True:
client, addr = server.accept()
print("[*] Accepted connection from: {}:{}".format(addr[0], addr[1]))
client_handler = threading.Thread(target=handle_client, args=(client,))
client_handler.start()*
Where I think an important distinction from your post may be that the server accepting connections is within an infinite loop. Have you tried this?
I have got a server.py and a client.py.
If i run them on the same computer using the same port and host as 127.0.0.1 it works fine.
I got another laptop connected to the same network. I got my local ip address 129.94.209.9 and used that for the server. On the other laptop I tried connecting to the server but I couldn't.
Is this an issue with my code, with the network or I'm just using the wrong ip address?
Server.py
HOST = '129.94.209.9'
PORT = 9999
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
sockfd, addr = server_socket.accept()
send and receive messages etc....
Client.py
HOST = '129.94.209.9'
PORT = 9999
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
except:
print("Cannot connect to the server")
send and receive messages etc...
Client prints "Cannot connect to the server"
Thanks!!
UPDATES: thanks for the comments
1) I did do sockfd, addr = server_socket.accept() sorry I forgot to add it, it was a few lines further down in the code.
2) The error is: [Errno 11] Resource temporarily unavailable
3) Ping does work
EDIT: It is working now when I plug both computers in by ethernet cable to the same network. Not sure why my the won't work when they are right next to each other connected to wifi.
Thanks for all the suggestions! I'll investigate the network issue myself
Using the following code (my IP address rather than yours, of course) I see the expected behaviour.
so8srv.py:
import socket
HOST = '192.168.33.64'
PORT = 9999
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
print("Listening")
s = server_socket.accept()
print("Connected")
so8cli.py:
import socket
HOST = '192.168.33.64'
PORT = 9999
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
except Exception as e:
print("Cannot connect to the server:", e)
print("Connected")
When I run it, the server prints "Listening". When I then run the client, both it and the server print "Connected".
You will notice that, unlike your code, my client doesn't just print hte same diagnostic for any exception that's raised, but instead reports the exception. As a matter of sound practice you should avoid bare except clauses, since your program will then take the same action whether the exception is caused by a programming error or a user action such as KeyboardInterrupt.
Also try using this construction to obtain the IP address:
HOST=socket.gethostbyname(socket.gethostname())