There are many threads regarding how to detect if a socket is connected or not using various methods like getpeername / getsockopt w/ SO_ERROR. https://man7.org/linux/man-pages/man2/getpeername.2.html would be a good way for me to detect if a socket is connected or not. The problem is, it does not say anything about if the connection is in progress... So if i call connect, it is in progress, then i call getpeername, will it say it is an error (-1) even though the connection is still in progress?
If it does, I can implement a counter-like system that will eventually kill the socket if it is still in progress after x seconds.
Short Answer
I think that, if getpeername() returns ENOTCONN, that simply means that the tcp connection request has not yet succeeded. For it to not return ENOTCONN, I think the client end needs to have received the syn+ack from the server and sent its own ack, and the server end needs to have received the client's ack.
Thereafter all bets are off. The connection might subsequently be interrupted, but getpeername() has no way of knowing this has happened.
Long Answer
A lot of it depends on how fussy and short-term one wants to be about knowing if the connection is up.
Strictly Speaking...
Strictly speaking with maximum fussiness, one cannot know. In a packet switched network there is nothing in the network that knows (at any single point in time) for sure that there is a possible connection between peers. It's a "try it and see" thing.
This contrasts to a circuit switched network (e.g. a plain old telephone call), where there is a live circuit for exclusive use between peers (telephones); provided current is flowing, you know the circuit is complete even if the person at the other end of the phone call is silent.
Note that if the two computers were connected by a single Ethernet cable (no router, no switches, just a cable between NICs), that is effectively a fixed circuit (not even a circuit-switched network).
Relaxing a Little...
Focusing on what one can know about a connection in a packet switched network. As others have already said, the answer is that, really, one has to send and receive packets constantly to know if the network can still connect the two peers.
Such an exchange of packets occurs with a tcp socket connect() - the connecting peer sends a special packet to say "please can I connect to you", and the serving peer replies "yes", the client then says "thank you!" (syn->, <-syn+ack, ack->). But thereafter the packets flow between peers only if the applications send and receive data, or elects to close the connection (fin).
Calling something like getpeername() I think is somewhat misleading, depending on your requirements. It's fine, if you trust the network infrastructure and remote computer and its application to not break, and not crash.
It's possible for the connect() to succeed, then something breaks somewhere in the network (e.g. the peer's network connection is unplugged, or the peer crashes), and there is no knowledge at your end of the network that that has happened.
The first thing you can know about it is if you send some traffic and fail to get a response. The response is, initially, the tcp acks (which allows your network stack to clear out some of its buffers), and then possibly an actual message back from the peer application. If you keep sending data out into the void, the network will quite happily route packets as far as it can, but your tcp stack's buffers will fill up due to the lack of acks coming back from the peer. Eventually, your network socket blocks on a call to write(), because the local buffers are full.
Various Options...
If you're writing both applications (server and client), you can write the application to "ping pong" the connection periodically; just send a message that means nothing other than "tell me you heard this". Successful ping-ponging means that, at least within the last few seconds, the connection was OK.
Use a library like ZeroMQ. This library solves many issues with using network connections, and also includes (in modern version) socket heartbeats (i.e. a ping pong). It's neat, because ZeroMQ looks after the messy business of making, restoring and monitoring connections with a heartbeat, and can notify the application whenever the connection state changes. Again, you need to be writing both client and server applications, because ZeroMQ has it's own protocol on top of tcp that is not compatible with just a plain old socket. If you're interested in this approach, the words to look for in the API documentation is socket monitor and ZMQ_HEARTBEAT_IVL;
If, really, only one end needs to know the connection is still available, that can be accomplished by having the other end just sending out "pings". That might fit a situation where you're not writing the software at both ends. For example, a server application might be configured (rather than re-written) to stream out data regardless of whether the client wants it or not, and the client ignores most of it. However, the client knows that if it is receiving data it then also knows there is a connection. The server does not know (it's just blindly sending out data, up until its writes() eventually block), but may not need to know.
Ping ponging is also good in that it gives some indication of the performance of the network. If one end is expecting a pong within 5 seconds of sending a ping but doesn't get it, that indicates that all is not as expected (even if packets are eventually turning up).
This allows discrimination between networks that are usefully working, and networks that are delivering packets but too slowly to be useful. The latter is still technically "connected" and is probably represented as connected by other tests (e.g. calling getpeername()), but it may as well not be.
Limited Local Knowledge...
There is limited things one can do locally to a peer. A peer can know whether its connection to the network exists (e.g. the NIC reports a live connection), but that's about it.
My Opinion
Personally speaking, I default to ZeroMQ these days if at all possible. Even if it means a software re-write, that's not so bad as it seems. This is because one is generally replacing code such as connect() with zmq_connect(), and recv() with zmq_revc(), etc. There's often a lot of code removal too. ZeroMQ is message orientated, a tcp socket is stream orientated. Quite a lot of applications have to adapt tcp into a message orientation, and ZeroMQ replaces all the code that does that.
ZeroMQ is also well supported across numerous languages, either in bindings and / or re-implementations.
man connect
If the initiating socket is connection-mode, .... If the connection cannot be established immediately and O_NONBLOCK is not set for the file descriptor for the socket, connect() shall block for up to an unspecified timeout interval until the connection is established. If the timeout interval expires before the connection is established, connect() shall fail and the connection attempt shall be aborted.
If connect() is interrupted by a signal that is caught while blocked waiting to establish a connection, connect() shall fail and set errno to [EINTR], but the connection request shall not be aborted, and the connection shall be established asynchronously.
If the connection cannot be established immediately and O_NONBLOCK is set for the file descriptor for the socket, connect() shall fail and set errno to [EINPROGRESS], but the connection request shall not be aborted, and the connection shall be established asynchronously.
When the connection has been established asynchronously, select() and poll() shall indicate that the file descriptor for the socket is ready for writing.
If the socket is in blocking mode, connect will block while the connection is in progress. After connect returns, you'll know if a connection has been established (or not).
A signal could interrupt the (blocking/waiting) process, the connection routine will then switch to asynchronous mode.
If the socket is in non blocking mode (O_NONBLOCK) and the connection cannot be established immediately, connect will fail with the error EINPROGRESS and like above switching to asynchronous mode, that means, you'll have to use select or poll to figure out if the socket is ready for writing (indicates established connection).
I have a question on Client-Server-Computing.
Why is there only one connection from the server back to the client? In UNIX you normally have stdout and stderr.
Background:
Database-queries might take a much longer time than you expected.
Then you wonder if there is something wrong. Maybe the server is stuck in an endless loop. This can easily be the case because servers nowadays can be extended via procedures, triggers etc.
If there was an extra port for sending status messages from the server to the client the user could get the information "everything ok" e.g. via "executing node number 7 of the query execution plan".
These users who only would be puzzeld by such information could keep the message window closed.
Is there a real technical problem or need those responsible for TCP standardisation just a hint?
TCP is a generic transport protocol and does not distinguish between different semantics, like status, error, data, ... Such semantics are added by the application protocol on top of TCP.
To provide different semantics it is not necessary to have different TCP connections. One could easily define an application protocol which allow messages with different semantics to be transferred over the same TCP connection. And such protocols exist, for example TLS (handshake messages, application data, alerts ...). But one could also do multiple TCP connections, like in FTP with different TCP connections for control and data.
So the question should be instead why a specific server application does not have the capability for status updates in parallel to queries. It is definitely not because of limitations from using TCP as transport layer, but because of limitations in the application itself.
So I have a PC connected to a micro-controller via a serial cable and an Ethernet cable. Initially the PC sends a byte across the serial cable to the micro-controller. This results in the micro-controller sending back a UDP datagram via the Ethernet cable.
I want to know whether the code running on my PC should be a server or a client?
Per Wikiepdia Client/Server:
The server component provides a function or service to one or many
clients, which initiate requests for such services
And Master/Slave:
Master/slave is a model of asymmetric communication or control where
one device or process controls one or more other devices or processes
and serves as their communication hub
The above scenario looks like the Master/Slave. In the initial, 'idle' case, there is no "SERVER" that is waiting ("listening") for requests. Only when the PC activate the micro-controller they will start communication (via UDP).
You could use either term depending on what you were talking about. As other people have noted, client and server are terms used to describe how distinct parties are involved in a service. The terms can be useful in some situations (e.g. a web server and the browser as a client) but in other situations it's a less useful term (e.g. peer-to-peer protocols).
Presumably you're on stackoverflow because you're dealing with code.
In this case it's useful to be more precise and I'd suggest using terms to match whatever primitives are exposed by your language. Most will use/expose Posix sockets as their standard API, and hence you'd want to talk about/use connect or accept (potentially after binding first). Note that these calls work across TCP and UDP (except accept), but the semantics of sending and recving on the resulting connected sockets will obviously be different.
I'm trying code TCP server in C language. I just noticed accept() function returns when connection is already established.
Some clients are flooding with random data some clients are just sending random data for one time, after that I want to close their's current connection and future connections for few minutes (or more, depends about how much load program have).
I can save bad client IP addresses in a array, can save timings too but I cant find any function for abort current connection or deny future connections from bad clients.
I found a function for windows OS called WSAAccept that allows you deny connections by user choice, but I don't use windows OS.
I tried code raw TCP server which allows you access TCP packet from begin including all TCP header and it doesn't accept connections automatically. I tried handle connections by program side including SYN ACK and other TCP signals. It worked but then I noticed raw TCP server receiving all packets in my network interface, when other programs using high traffic it makes my program laggy too.
I tried use libnetfilter which allows you filter whole traffic in your network interface. It works too but like raw TCP server it also receiving whole network interface's packets which is making it slow when there is lot of traffic. Also I tried compare libnetfilter with iptables. libnetfilter is slower than iptables.
So in summary how I can abort client's current and future connection without hurt other client connections?
I have linux with debian 10.
Once you do blacklisting on packet level you could get very fast vulnerable to very trivial attacks based on IP spoofing. For a very basic implementation an attacker could use your packet level blacklisting to blacklist anyone he wants by just sending you many packets with a fake source IP address. Usually you don't want to touch these filtering (except you really know what you are doing) and you just trust your firewall etc. .
So I recommend really just to close the file descriptor immediately after getting it from accept.
I'm real noob in C. I'm trying to develop my own lock-server in C (just for practice). And I have a question... Let's imagine that we have server written in C, we have remote host connected to this server via socket. When connection being initiated - my server has created pointer in memory. Is it possible to remove this pointer when remote host has disconnected? How can I catch disconnect event?
Thank you
In a real world io scenario, you cannot truly detect the disconnection. Instead you must:
Receive a packet that indicates the other side intends to disconnect.
Attempt to transmit a package which will fail to be delivered due to changes in the connectivity during the "silent" period between communications.
This means that systems which "must" ensure connectivity typically send and receive periodic "dummy" messages to detect the loss of the connection sooner than it would be detected by "regular" traffic alone.
Depending on your application the overhead of the keep-alive messages may not be worth the effort.
The "connection" you have on your side of the network is really just a bunch of data structures which allow you to transmit and receive. The lower "IP" layer of "TCP/IP" is connectionless, that means you will not know if your simulated "connection" is available until you attempt to use it (or receive a package telling you explicitly that the other end will not process any more data).
The read(2) system call will return zero when the other end of the socket closes the connection.