Connection time out of TCP write (netstat shows ESTABLISHED) - c

I made an experiment:
A server listens on port 8804 accepts a connection of a client and then send data to the client endless. I shutdown the network.
When I run netstat -anotp | grep 8804 ,it shows that the connection is "ESTABLISHED" on both server and client , but there is no data transmission.
After a while , the server throw an error : "Connection time out"
netstat -anotp | grep 8804 and found that the client is still "ESTABLISHED"
So:
1. Why does the server which is blocked on the system call "write" throw the "Connection timeout" error. Why not the client ?
2. How to let the client find the connection is shutdown actually.
3. Why are the server and client's statuses both "ESTABLISHED" when the network does not work ?
Thanks for your answer !

Your server is expecting TCP ACKs for individual data segments that it sends to the client; however, the client has no idea how long the server's data is. Since you shutdown the network the server no longer gets ACKs from the client. Result: Connection timeout on the server (See Note 1)
Use TCP Keepalives on your socket (See Note 2)
You have not enabled TCP Keepalives. If you are using python, you can do so like this (assuming your socket is named s):
# Do this before you accept() anything on the socket
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
EDIT:
Since you're using C, a link to the Linux TCP Keepalives Howto
NOTES
RFC 1122: Section 4.2.3.5 "TCP Connection Failures"
RFC 1122: Section 4.2.3.6 "TCP Keepalives"

Related

Client create connection to unknown Server IP

I 'm using C language to create a connection from client to server. I use a command:
iResult = connect(ServerSocket,(LPSOCKADDR)&addr, nSize);
In most of cases, when an server IP (in "addr") is recognized or in local network, it returns the result (fail or Ok) immediately, but if it is an IP out side of local network or non-existed IP, the time out for connection is quite long, cannot response for a real time processing. So, could you please tell me any idea a bout how to set the timeout (several millisecond) for this command? Thanks for your help.
You can find an example in this article:
How to set a socket connection timeout
Basically you have to use non-blocking socket I/O and use some form of I/O multiplexing (like select or poll).

c linux sockets: check for existing connections from client side

I have the following setup:
2 Ubuntu machines (server and client)
on the "server" I'm running this to echo all the data received back to the sender (the client):
ncat -e /bin/cat -v -l 12345
on the client I have simple application which just connects to the remote socket: socket() -> setsockopt() -> connect()
So... my question is: Is it possible to check if there are other applications already connected to the socket from the client application? I want only one process connected to the socket at any given time and I want to check this from the client application. Is this possible? After 3h googling I couldn't find anything relevant :(
(sorry, no experience with network programming)
No, a client is not able to see how many other clients are connected to a server.
To be able to retrieve this information an application specific protocol needs to be used on client and server.
Anyhow there is this one special case: If the client knows that a maximum of N clients can connect to the server, and it's own try to connect is refused it could assume that N clients are connected to the server already.
To set the maximum number of connections ncat handles in parallel use it's option -m/--max-conns. Verbatim form man ncat:
-m numconns, --max-conns numconns (Specify max number of connections) .
The maximum number of simultaneous connections accepted for an Ncat instance. 100 is the default.
Run:
netstat -an | grep <your server port port number>
on your client machine to see any existing TCP connections.
Can you not close the listening socket on the server after you've accepted one client? If there's no listening socket no more clients will be able to connect. Once you've dropped your one client, you can then open the listening socket again, ready for one more. That way the client will see a "failure" to connect if the server is busy, or will succeed normally otherwise.
The down side of this approach is that the client won't be able to determine exactly why it can't connect, it could be because the client is busy (has its one client) or it could be because of other issues. Does this matter?

Multiple TCP connections in C

Can a process open/maintain 2 TCP connections in parallel? [for sending and receiving].
I tried the following scenario :
1) Client connects to server on one port, say 13101.
2) Once it sends, it will wait on another port 13102 to get the ACK.
3) Here Server can handle multiple connections [using select() on same port number].
Now, I am facing 2 problems:
1) Server on receiving data from Client1, it is processing data and for sending the ACK back [to client1], I am preparing a new TCP connection [with port 13102] and trying to send data. It fails with "Connection Refused".
2) In order to verify the above problem, I wrote another client2 program that just sends data to port 13102 [to client1, when it is in listening mode]. Still client2 is getting "Connection refused" error.
Yes, you can open lots of sockets! However, you shouldn't need separate sockets for sending and receiving, a TCP socket is bi-directional once it's opened.
As for your error, if you're using two machines, there could be a firewall preventing the server from connecting to your client. You might try using telnet to try to connect to the same port.
The error is probably because the client is not listening for an incoming connection. As stated above you can use a single socket for both send and receive.

TCP connection - delayed close() and RST

I have both TCP client and TCP server run on RHEL 5.3 on different machines.
I'm killing server and FIN is sent to the client. ACK is sent back by client's OS back immediately.
Client discovers the close (by read() returning zero) and perfroms close only after 90 sec.
At this stage I verified netstat on both sides and it's as expected (FIN_WAIT_2 on server and CLOSE_WAIT on client).
Due client close() after 90 sec, client's OS sends FIN to server, but in response we receive RST from server and not ACK as expected.
I also saw several times that due to "delayed" close(), client's OS sent RST instead of FIN.
Please note, that in both cases there's no pending reading packets on both sides and SO_LINGER option is not activated.
Any ideas?
The RST indicates that some "data" was lost. In this case, the "data" is the information that the client side closed the socket cleanly - the FIN from the client was not reported to the server side application (because it had been killed).
In other words, the RST tells the client that the server never saw end-of-stream from the client.

What can be the reasons of connection refused errors?

I'm trying to write a server program in C,
using another client, I get this error when I try to connect through port 2080 for example.
connection refused
What can be the reasons of this error?
There could be many reasons, but the most common are:
The port is not open on the destination machine.
The port is open on the destination machine, but its backlog of pending connections is full.
A firewall between the client and server is blocking access (also check local firewalls).
After checking for firewalls and that the port is open, use telnet to connect to the ip/port to test connectivity. This removes any potential issues from your application.
The error means the OS of the listening socket recognized the inbound connection request but chose to intentionally reject it.
Assuming an intermediate firewall is not getting in the way, there are only two reasons (that I know of) for the OS to reject an inbound connection request. One reason has already been mentioned several times - the listening port being connected to is not open.
There is another reason that has not been mentioned yet - the listening port is actually open and actively being used, but its backlog of queued inbound connection requests has reached its maximum so there is no room available for the inbound connection request to be queued at that moment. The server code has not called accept() enough times yet to finish clearing out available slots for new queue items.
Wait a moment or so and try the connection again. Unfortunately, there is no way to differentiate between "the port is not open at all" and "the port is open but too busy right now". They both use the same generic error code.
If you try to open a TCP connection to another host and see the error "Connection refused," it means that
You sent a TCP SYN packet to the other host.
Then you received a TCP RST packet in reply.
RST is a bit on the TCP packet which indicates that the connection should be reset. Usually it means that the other host has received your connection attempt and is actively refusing your TCP connection, but sometimes an intervening firewall may block your TCP SYN packet and send a TCP RST back to you.
See https://www.rfc-editor.org/rfc/rfc793 page 69:
SYN-RECEIVED STATE
If the RST bit is set
If this connection was initiated with a passive OPEN (i.e., came
from the LISTEN state), then return this connection to LISTEN state
and return. The user need not be informed. If this connection was
initiated with an active OPEN (i.e., came from SYN-SENT state) then
the connection was refused, signal the user "connection refused". In
either case, all segments on the retransmission queue should be
removed. And in the active OPEN case, enter the CLOSED state and
delete the TCB, and return.
Connection refused means that the port you are trying to connect to is not actually open.
So either you are connecting to the wrong IP address, or to the wrong port, or the server is listening on the wrong port, or is not actually running.
A common mistake is not specifying the port number when binding or connecting in network byte order...
Check at the server side that it is listening at the port 2080.
First try to confirm it on the server machine by issuing telnet to that port:
telnet localhost 2080
If it is listening, it is able to respond.
1.Check your server status.
2.Check the port status.
For example 3306 netstat -nupl|grep 3306.
3.Check your firewalls.
For example add 3306
vim /etc/sysconfig/iptables
# add
-A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
Although it does not seem to be the case for your situation, sometimes a connection refused error can also indicate that there is an ip address conflict on your network. You can search for possible ip conflicts by running:
arp-scan -I eth0 -l | grep <ipaddress>
and
arping <ipaddress>
This AskUbuntu question has some more information also.
I get the same problem with my work computer.
The problem is that when you enter localhost it goes to proxy's address not local address you should bypass it follow this steps
Chrome => Settings => Change proxy settings => LAN Settings => check Bypass proxy server for local addresses.
In Ubuntu, Try
sudo ufw allow <port_number>
to allow firewall access to both of your server and db.
From the standpoint of a Checkpoint firewall, you will see a message from the firewall if you actually choose Reject as an Action thereby exposing to a propective attacker the presence of a firewall in front of the server. The firewall will silently drop all connections that doesn't match the policy. Connection refused almost always comes from the server
In my case, it happens when the site is blocked in my country and I don't use VPN.
For example when I try to access vimeo.com from Indonesia which is blocked.
Check if your application is bind with the port where you are sending the request
Check if the application is accepting connections from the host you are sending the request, maybe you forgot to allow all the incoming connections 0.0.0.0 and by default, it's only allowing connections from 127.0.0.1
I had the same message with a totally different cause: the wsock32.dll was not found. The ::socket(PF_INET, SOCK_STREAM, 0); call kept returning an INVALID_SOCKET but the reason was that the winsock dll was not loaded.
In the end I launched Sysinternals' process monitor and noticed that it searched for the dll 'everywhere' but didn't find it.
Silent failures are great!

Resources