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
Related
I'll try be concise, but please let me know if I can provide any more helpful pieces of information.
I have client and server Python programs, and they work fine when ran on the same machine, and when the client connects to my machine's local IP (not 127.0.0.1, but the IP assigned to my machine). I have not been able to get this to work with my public IP.
I get a [Errno 61] Connection refused error when I try to get the client to connect to my router's public IP address. My server binds to all interfaces using bind(("0.0.0.0", 50000)), and I already set up port forwarding for my router. I verified that the program is listening on that port by running netstat -an | grep LISTEN and finding the following line:
tcp4 0 0 *.50000 *.* LISTEN
I can also seemingly reach the port through an online port checking tool, which shows that the port is open when I am running my program, and closed when I close that program. My program also registers the connection from this tool.
The fact that my program accepts the connection from the port checking tool gives me the impression that my client code is missing something, but I can't find any answers. It might be worth noting that I am still running my server and client code on the same machine, but I'm not sure why that would derail things. Here's the code I use to connect on the client side:
tcp_client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
tcp_client.connect(('my_public_ip', 50000))
Are there any diagnostic steps that I can follow to narrow down my issue?
Before you spend any more time on this, try connecting to your public ip from a computer outside your home network. Spend a couple of dollars on an AWS instance for an hour if you have to, or try connecting from a friend's machine, whatever. It will probably work just fine.
I suspect the problem is simply that you cannot, from inside your home network, connect to your router's public ip address. I tried the same thing with my local network and ran into the same behavior.
If you really need to your public ip during development, you can just assign that as an alias to one of your local interfaces (ip addr add 1.2.3.4/32 dev eth0)...but it's probably easier just to use your an address on your local network, or just arrange for regular access to a remote system for testing.
In my GO code, I am establishing a TCP connection as below:
conn, err1 := net.Dial("tcp", <remote_address>)
if err1 == nil {
buf := make([]byte, 256)
text, err := conn.Read(buf[:])
if err == io.EOF {
//remote connection close handle
fmt.Println("connection got reset by peer")
panic(err)
}
}
To simulate the other end, I am running a python script on a different computer, which opens a socket and sends some random data to the socket above lines of codes are listening to. Now my problem is, when I am killing this python code by pressing ctrl+C, the remote connection closed event is recognised finely by above code and I get a chance to handle that.
However, if I simply turn off the remote computer (where the python script is running) my code doesn't get notified at all.
In my case, the connection should always be opened and should be able to send the data randomly, and only if the remote machine gets powered off, my GO code should get notified.
Can someone help me in this scenario, how would I get notification when the remote machine hosting the socket itself gets powered off? How would I get the trigger remotely in my GO code?
PS - This seems to be a pretty common problem in real time, though not in the testing environment.
There is no way to determine the difference between a host that is powered off and a connection that has been broken, so you treat them the same way.
You can send a heartbeat message on your own, and close the connection when you reach some timeout period between heartbeat packets. The timeout can either be set manually by timing the packets, or you can use SetReadDeadline before each read to terminate the connection immediately when the deadline is reached.
You can also use TCP Keepalive to do this for you, using TCPConn.SetKeepAlive to enable it and TCPConn.SetKeepAlivePeriod to set the interval between keepalive packets. The time it takes to actually close the connection will be system dependent.
You should also set a timeout when dialing, since connecting to a down host isn't guaranteed to return an ICMP Host Unreachable response. You can use DialTimeout, a net.Dialer with the Timeout parameter set, or Dialer.DialContext.
Simply reading through the stdlib documentation should provide you with plenty of information: https://golang.org/pkg/net/
You need to add some kind of heartbeat message. Then, looking at GO documentation, you can use DialTimeout instead of Dial, each time you receive the heartbeat message or any other you can reset the timeout.
Another alternative is to use TCP keepalive. Which you can do in Python by using setsockopt, I can't really help you with GO but this link seems like a good description of how to enable keepalive with it:
http://felixge.de/2014/08/26/tcp-keepalive-with-golang.html
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.
I would try connect to a counterstrike server hosted on my ip through python socketing ...
import socket
s = socket.socket()
s.connect(("localhost", 27015))
But I would get an error
error: [Errno 10061] No connection could be made because the target machine actively refused it
And I'm sure the server is up, so I'm not sure why it wouldn't connect, I could connect to it in game.
To debug such things you can use Wireshark to observe your Python script while it is trying to connect and compare it to a real client. You may have to listen on the "localhost" interface instead of your physical network interface to see the connection. Your server needs to do the same, so ask your OS to give you a list of bound sockets, including the IPs they are bound to (on Linux netstat -nlp) to check. Maybe the server needs to be configured to allow non-public IPs. Finally, make sure you got the protocol right, TCP (SOCK_STREAM) vs UDP (SOCK_DGRAM).
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.