I'm trying to implement a simple example of a distributed producer consumer, and while testing, I always get the following error:
OSError: [WinError 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
Even though many posts claim that s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) before bind would allow me to ignore the TIME_WAIT, I still get the same exception when trying to connect for a second time.
server.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 4330))
s.listen()
s.accept()
s.close()
client.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 4334))
s.connect((myaddress, 4330))
s.close()
When client socket closed locally, if you try to connect to the same destination again, with recreated socket of same ip:port, TIME_WAIT will be in effect, regardless of SO_REUSEADDR.
To avoid this, you can make the server to initiate close() first.
Please refer this answer and this article for more details.
Related
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!
I know this was already asked but the previous questions didn't help. I'm trying to send some data using sockets. Specifically I'm using my laptop as server and a Linux emulator (Termux) on my smartphone as a client. Here below you can see the two Python codes. For the server:
import socket
HOST = ''
PORT = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
print('Connected by', addr)
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
s.close()
And for the client:
import socket
HOST = ''
PORT = 5555
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', repr(data))
s.close()
When I'm connected to the same WiFi and in HOST (in both codes) I put the IP I see from ipconfig (192.168.---.---) everything works. It also works if in the HOST of the server I put 0.0.0.0.
However, when I put the IP of the machine (that I can see on https://whatismyipaddress.com/) and instead of using the WiFi I use the phone connection I get: ConnectionRefusedError: [Errno 111] Connection Refused.
Can someone explain me how can I connect client and server when the networks are different? I have been stuck with this for a while.
I also tried to open a port on the Firewall following this procedure and put it in the code instead of 5555 but still it didn't work.
Thank you in advance for the help.
I want to implement tcp check with Python.
I found a magic way in this article.
It introduce a efficient way to do a tcp-health-check.
Client: SYN
Server: SYN-ACK
Client: RST
I also found a Go implementer https://github.com/tevino/tcp-shaker.
But i hope to implement SYN,SYN-ACK,RST in python.
My code is there:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_TCP, socket.TCP_QUICKACK, 0)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 0)
s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', 1, 0))
s.connect((ip, port))
s.close()
But it didn't work as I expected. The client send a ACK to the server when the SYN-ACK received from server.
How could I disable TCP_QUICKACK in Python?
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())
So I have create a socket and am using the function socket.bind() and keep on getting the following error: Only one usage of each socket address (protocol/network address/port) is normally permitted
Here is my code:
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host, port))
s.listen(5)
while True:
c , addr = s.accept()
print('Thank you for connecting to', addr)
c.send('Hello and thanks for connecting')
c.close()
The port / ip combination is bound already. You can not bind it again. You should check if an other instance of your program is still running. If not, use an other port.