I am trying to do some simple sockets programming in Python. I have a UDP server in Python that accepts an input and sends a response. I'm having trouble with the client code.
sock = socket.socket(
socket.AF_INET, socket.SOCK_DGRAM
)
sock.bind(('0.0.0.0', 0))
sock.settimeout(2)
sock.sendto(json.dumps({
'operation': operation,
'operands': [operand1, operand2]
}), (host, port))
print sock.recvfrom(4096)
This code works perfectly when the server is running. However, when I try it without the server running, the code throws an exception immediately instead of blocking on recvfrom().
socket.error: [Errno 10054] An existing connection was forcibly closed by the remote host
My desired functionality would be to timeout after some time.
Can anyone explain what I am doing wrong? I use recvfrom in the server code and it blocks, so I'm a little puzzled at what the difference is.
Much of the former answer doesn't apply, since you have a SOCK_DGRAM type, i. e. UDP socket. UDP is a connectionless service, even though the error message talks about connection. The exception occurs due to a notification from the destination host in response to the sendto datagram, telling that the port is unreachable; this notification is processed (perhaps even arrives) not before you call recvfrom. There is no automatic retry; you have to try the recvfrom (maybe as well the sendto) again and implement the desired timeout yourself.
There are plenty possible reasons for that.
Socket error [10054] means connection reset by peer.
An existing connection was forcibly closed by the remote host. This normally results if the peer application on the remote host is suddenly stopped, the host is rebooted, the host or remote network interface is disabled, or the remote host uses a hard close (see setsockopt for more information on the SO_LINGER option on the remote socket). This error may also result if a connection was broken due to keep-alive activity detecting a failure while one or more operations are in progress. Operations that were in progress fail with WSAENETRESET. Subsequent operations fail with WSAECONNRESET.
Check this link for details.
You need to look into it to figure out what actually happened. I don't have your environment so I cannot locate what the real problem is.
Hope this helps.
Related
I have hardware which has the ability to receive data/commands via ethernet or serial.
I am doing socket programming in python to send commands to the hardware. Everything works fine, but once I close the socket (it closes successfully) and then when I try to reinit and create the socket in a different program, it throws me CONNECTION REFUSED
The only workaround for now is to remove the ethernet cable from the network switch and plug back in. and then it works and again once socket is closed and then want to reopen it, Connection refused error pops up.
Since the server code is running on proprietary hardware, I don't have access to it. I can only configure the port and ip address of the hardware.
Here is the snapshot of the program with the error message
and also the wireshark snapshot
and when I removed the ethernet wire and reconnected again , it can connect properly
see this snapshot.. so not sure where is gng wrong
Please let me know if you have any questions
This happens because the server is not running on that ip and or port.
This error is common. Try check through this:
Ensure that there are no other identical addresses. This is
important.
Make sure that the server is running before booting up the client.
Make sure the client has access to the server and the server can accept connections.
Make sure that the maximum connection setting is high enough to allow an ideal amount of connections. If this is not enabled then all
other connections get booted
Also when you said that the only way for you to get it to work is to reconnect your Ethernet cable, this is probably because you have a closed connection. You must set a loop so that the connection can be kept open
I am trying to create a socket between using UDP in python.
The code is quite straightforward
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(data_to_send, (host, port))
received_data = s.recvfrom(1024)
My question is, are sendto and recvfrom blocked methods?
That is, when I invoke sentdo will my code stop and wait for recvfrom, because, I am goofing around and testing client and server model on my localhost, and manually injecting random sleep times of 3 and 4 seconds to simulate real life delays, and I am getting ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host in case the latency is a bit high.
These calls may block the thread they're being executed in.
sendto will block if the outbound buffer of your OS kernel is full and it needs time to become able to accommodate the message you are willing to send. sendto won't block because the remote application haven't called recvfrom yet.
recvfrom will block until there's something to read from the inbound buffer of your OS kernel. recvfrom will block if the remote peer hasn't sent anything or the message has not arrived yet.
Also, there's probably some misconfiguration happening on your side. ConnectionResetError may happen because there's a firewall somewhere. Latency is not related to the issue since UDP has no connections and timeouts.
I'm using a TCP socket to connect to a certain web page, as it will be running in a loop trying to create socket, connect, send data, and receive then close the socket. the problem is s.connect() times out at random iterations and specific web site. i read about TCP time_wait so
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
was added with no luck. then one second of sleep after each iteration, but still no luck.
i should note that it works fine in another slower network, but not in the fast one i'm trying to run the code.
i think following pseudo code can clarify it more:
while(1)
{time.sleep(1)
s = socket.socket() #TCP socket creation
s.settimeout(2) # 2 seconds for time-out which is more than needed
s.connect()
s.send(message) #which is a HTTP get request
s.recv() # which is a HTTP response
s.close()}
my code routine follows these steps, each of socket methods are implemented correctly, but i get time-outs on connect. i am sure about server functioning correctly. i suspected it might have something to do with TCP time_wait , but comments don't seem to agree
A connect times out if the TCP handshake with the server is not finished within a specific time, usually because the server does not respond in time. There might be various reasons for is, like the server being down, getting the wrong IP address for the server during DNS lookup, server being overloaded etc.
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
Adding this on the client side on the connection has no use.
Adding this on the server side will help if the problem was caused by a crashed server since it will allow the server to bind to the listener address again without waiting and thus the server is faster available again. But, I have no idea if this is really the problem you are facing.
From http://docs.python.org/2/howto/sockets.html
if a socket send or recv returns after handling 0 bytes, the
connection has been broken.
On the other hand, if the remote end of the TCP connection closes (or is killed), and socket.send() is called subsequently, one can see the following socket.error exception
socket.error: [Errno 104] Connection reset by peer
Now my question is, what is the difference between "connection has been broken" and "Connection reset by peer". And exactly what is meant by "connection has been broken" == socket.send() returns zero. To me, not being able to send even a single character is as bad as a socket.error exception. Whatever event that causes socket.send to return zero, should have ideally raised a socket.error exception, so that the application does not have to deal with two different things (exception and return value zero).
Getting RST is a very specific use-case in TCP protocol -- the peer sends a message back by setting the RST flag in the TCP header. It usually means that there is no socket endpoint at the peer. This scenario can happen if hte remote peer's machine rebooted suddenly without having a chance to close the socket gracefully (aka by using 4-way FIN messages). Once it comes back online, it has lost the earlier socket endpoint and if it recieves any new TCP packet for the older connection, then it will send a TCP message by setting the RST flag.
As opposed to receiving a RST, a connection could be closed due to other reasons. One of them them being a normal graceful of using the FIN messages. In such cases, the underlying connection at the TCP layer is closed. The other case could be that the the peer's connectivity was lost and there is a TCP Keepalive option set. For this case, when the peer becomes idle, TCP would send keepalive probes and since the connectivity is not there, there would be no replies to the Keepalive. Once the TCP layer does not receive a set of N keepalives, then it will close the connection locally. Calling Python's send and recv on such a socket returns 0.
I am running a Graphite server to monitor instruments at remote locations. I have a "perpetual" ssh tunnel to the machines from my server (loving autossh) to map their local ports to my server's local port. This works well, data comes through with no hasstles. However we use a flaky satellite connection to the sites, which goes down rather regularly. I am running a "data crawler" on the instrument that is running python and using socket to send packets to the Graphite server. The problem is, if the link goes down temporarily (or the server gets rebooted, for testing mostly), I cannot re-establish the connection to the server. I trap the error, and then run socket.close(), and then re-open, but I just can't re-establish the connection. If I quit the python program and restart it, the connection comes up just fine. Any ideas how I can "refresh" my socket connection?
It's hard to answer this correctly without a code sample. However, it sounds like you might be trying to reuse a closed socket, which is not possible.
If the socket has been closed (or has experienced an error), you must re-create a new connection using a new socket object. For this to work, the remote server must be able to handle multiple client connections in its accept() loop.