Python: sockets randomly disconnecting on local network - python

I'm trying to run a python socket server on my local network, with this server code:
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind((socket.gethostname(), 9876))
serversocket.listen(5)
while True:
c, addr = serversocket.accept()
while True:
data = c.recv(1024).decode()
print(data)
c.send(data.encode())
Then, using netcat on another network machine, I can connect to the server and send text in, and have it mirrored back. However, after about two or three tries, it suddenly drops back out to the command line and no longer accepts any connections. The server side, however acts the same, and appears like it didn't see the last incoming message.
If I try to connect to it with another socket, it does the same thing, but instead throws error 104, and then error 32.
I am completely stumped. I've tried adding threads, and everything else that I can think of. If anyone on has any ideas on why this is happening, or ways to work around it, I'd love to hear. Thanks! I'm using python 3.5.
Thanks!

Related

Python socket.recv hanging

I'm trying to retrieve data from a PLC (AutomationDirect P2000). I have set up the PLC as the server with their software program (I can also connect to it with their software via Ethernet and use Wireshark to see it is in fact sending UDP packets to my machine at roughly every 200ms). I am trying to set up a very simple Python script to retrieve said data, without bothering to encode it or do anything with it, but my program hangs at the socket.recv(). Whenever I try to run it "Got here" will be printed, but "Now here" will not. From what I've read the fact that it hangs means there's no data to be received, but from my (limited) understanding of what I see on Wireshark this is not the case. I am pretty new to all of this and would appreciate any help.
I have tried using socket.recvfrom(), which produces the same result. I've also tried using socket.bind() instead of socket.connect() but I get a "The requested address is not valid in its context" exception. Additionally, I've tried playing around with various IPs and ports. For example, I've tried using IP = '' instead of the actual IP, and I've tried the source/destination information from Wireshark as what I try to bind or connect to, but nothing thus far has worked.
import socket
IP = '192.168.3.1'
PORT = 9999
BUFFER_SIZE = 4096
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((IP, PORT))
while True:
print("Got here")
data = s.recv(BUFFER_SIZE)
print("Now here")
print(f"Received {data}")
I am expecting to get a print out of the packet in byte format, but instead the program is hanging. If I try socket.bind() instead of socket.connect() I get an error message reading "...line 8, in
s.bind((IP, PORT))
OSError: [WinError 10049] The requested address is not valid in its context"
you can't use bind like this, because the ip address does not belong to your PC.
when you connect to the server, it (the server) doesn't send anything, but you try to get data from the server, so the socket awaits until it gets data, and only then it will continue the execution (this is called a blocking function, since it blocks the execution until it finishes).
The issue was with how I set up the PLC as the server. The UDP data I was seeing on port 9999 wasn't the communications I was thinking it was, and was only the inherent communication between the PLC and the network via its proprietary program. For anyone curious, I am using a P2000 PLC from AutomationDirect and initially I set it up as an EtherNet/IP Adapter following one of their videos, but I had to use the Custom Protocol over Ethernet functionality provided in the "Communications" section.

Socket 10048 response after socket.connect_ex

I have this little piece of code that returns a 10048 after printing the response
I have tried adding socket.SO_REUSEADDR and it did help for the first time. After running the program for the first time it prints 0. Which from my knowledge means the port is open, but after that it returns 10048. I have also tried changing the port.
This is my code:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
host = '127.0.0.1'
port = 1024
s.bind((host,port))
result = s.connect_ex((host,port))
print(result)
s.close()
I am not sure why it is returning this. I have looked everywhere but cant find an answer. I am trying to get it to return either 0 or 1. That why I can tell if the port is open or closed.
This cannot work when host is the local machine: you try to use the same port on same machine as both source and destination.
You must either use two different ports, or different machines on do not fix the source port and let the system choose one (do not bind before connect).

What does "Only one usage of each socket address is normally permitted" tell me when using sockets under Python?

I have a socket server under Python:
sock= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(0)
sock.bind((self._ipadress, port))
later I'm accepting incoming requests in a loop, using select.select:
connection, client_address = sock.accept()
...
select.select(...)
Note that connections can be closed by clients when they not need it anymore.
I tested my code with a python client and was able to observe that multiple connections can be easily handled simultaneously as expected.
However, very sporadically I get error:
“Only one usage of each socket address is normally permitted”
What does it tell me and when does it happen?
Multiple connections on the same port are definitely possible (I tested it), so why should there be only one usage permitted? This is against the principle, that multiple clients can be accepted by the same server.
I learned from
Python server "Only one usage of each socket address is normally permitted"
that it can be avoided by using SO_REUSEADDR.
But why is it required, since even after closing a connection by a client, the socket should still be able to accept other connections. Otherwise my program wouldn't work at all.
I'm at home now and not in the office, so I cannot test it, but I have even problems to understand the principles behind...
.

Make socket connection with push of button

So I'm running two raspberry pi's. One is acting as a hotspot (can't remember the exact software, DCP something?) and the other is connected to it through the WiFi.
Anyway, I want this connection to proceed on bootup, but the issue is, it will only work when I run the programs at the exact same time, and loops seem to fail it.
So here's my server.
Host = '' #I have my specific address here
PORT = 8000
s= socket(AF_INET, SOCK_STREAM)
def CamConn():
s.bind((Host, PORT))
s.listen(24) # I eventually want 24 rpi connected
Conn, addr = s.accept()
Conn.settimeout(1)
CamConn() is called via tkinter button.
My client
HOST= ''
PORT= 8000
s= socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
Biggest issue here is that they sort of connect, but don't really... The address becomes "in use" and I have to reboot the server to get it free again. I've tried using exceptions, but it runs into the same issue. I honestly have no idea why it's only half connecting?
Edit:
Guys, I'm going to put the clients in a tuple eventually, so there is no need for threading.
I'm using an after mainloop to ensure that the sockets and send and receive what's necessary.
All I'm asking is why this connection won't work when called on via a button. The client will hang, until the button is pressed in which it will recognise a connection, but it will fail to create a connection that can send or receive data.
Edit 2: I should also mention that I'm broadcasting identical information to all the other clients, every second. The only time the server recieves data is if an option is selected in which a photo will be sent.

I can't connect to socket from the outside

I am trying to make a simple server/client program pair.
On LAN they work fine, but when i try to connect from the "outside" it says connection refused. I shut down firewalls on both machines but i am still unable to connect, and i double checked the ip.
What am i doing wrong?
Thanks
Jake
Code:
import socket
host = ''
port = 9888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(1)
conn, adrr = s.accept()
conn.send("Hello, world!")
s.close()
Client:
import socket
host = '68.x.x.x'
port = 9888
s = socket.socket(socket.AF_INET, socket_SOCK_STREAM)
s.connect((host,port))
print s.recv(200)
s.close()
You have one of two possible issues.
Erroneous network configuration
Bug(s) in code
The way to debug this is to try and rule one out. If we can get rid of the Code issue then we know it is a network issue.
Get a Socket Server and client that you know works and then try them as standalone programs. inside and outside of the firewall.
Go to this site and download the examples. Change the ports in both the client and the server, compile and run them. First on same machine within network, second from two machines on same network and then server from within and client from outside of network.
How's the argument you're passing to the .bind call for your server socket? That's the single likeliest cause -- e.g. if you're using 192.168.x.y for whatever values of x and y, or 10.x.y.z likewise, that's a local-network address only, not routed by inter-network routers by internet conventions (most routers can be programmed to forward some incoming packets to a specific local-network address, typically depending on ports, but that's very specific to router's brands and models).

Categories

Resources