Say I have a public server on the Internet, written in C, that is connected to two independent clients. Both clients initiated the connection. One client is (e.g.) an iOS app, the other is a native Windows app.
The purpose of my server is to allow these clients to send text messages to each other. Client 1 sends a message, the server receives it, and then forwards it onto Client 2. The same thing happens in reverse when Client 2 sends a message.
This feels inefficient. What I would really like is for both of these connections to contact the server and then for the server to connect these two clients directly to each other - after which my server can forget both clients as they are responsible for communicating with each other. My server is then free to connect up other clients in the same way.
My question is: is this even possible (with TCP and/or UDP)? Neither client necessarily has a public IP address, which is why they have to initiate the connection. Once the connection is established however, my server knows the connection address of both clients. Is there a way to connect them together? A syscall that can do this sort of thing, perhaps?
No, you can not join two existing TCP connections to one.
There are 2 options:
1) Keep your server in the middle as it already is. It should not be problem, if you don't have thousands of clients under one server.
2) Server could send control messages to clients, and order those open new TCP connection between each other. Server should also make decision which of the two clients must be initiator of the new TCP connection.
Option 2 is problematic, because client may have firewall rule that prevents in coming connection to the wanted port. Also NAT would cause problems.
Related
I'm writting client-server programs, that using unix domain socket for communicating between two sides.
The requirement is:
Server opens an abstract socket on a given address, then listen on that. By some triggers, server can stop listening on that.
Client has to monitor that Server is listening on given address path or not
if server is listening on socket then send a register request to server
if server close the socket then do some action cleaning up...
To check the server is listening or not, my solution is:
Periodically create a socket and connect to server address path, if succeed, then means that server is listening, and vice versa for any case of error.
But the solution seems to be cpu-consuming if checking interval is too short.
Then my question is: do we have any method like registering some callback to system, and get the notification whenever some process starts/stops listening on a given address? or some other better suggestion...??
Many thanks,
I have a C service application that use tcp socket for connection to a server. The server sends data now and then. Also my application sends a hearbeat every 15 seconds. But sometimes it disconnects while server seems to think the connection is live. Now if I try to reconnect the server refuses as it holds only one connection for the client at a time.
What is the best way to hold a persistent tcp connection?
Edit:
The server usually disconnects after 2 min without heartbeat. So after I find my connection is closed it takes 2min for me to successfully reconnect. I want to minimize this time.
The simplest fix is probably for the server to allow a new connection to replace an old connection rather than rejecting it. That would still keep only one connection to each client at a time.
I would like to build a completed network(every node connects to remaining nodes). I have a group of peers, let say it includes P2P1, P2P2, P2P3. Assuming that all peers are running on a same machine(localhost). Every peer has a client side and server side that are written in a same file.
First P2P1 is initialized as "p2p Name_of_group Port_Number_for_Server_Side". Then
P2P2 as "p2p Name_of_group Port_Number_for_Server_Side Port_Number_of_P2P1". And then
P2P3 as "p2p Name_of_group Port_Number_for_Server_Side Port_Number_of_P2P2".
The client side of P2P2 connects to the server side of P2P1, the client side of P2P3 connects to the server side of P2P2.
Now P2P1 connects to P2P3(automatically in code , not from user). If there is a new peer, let say P2P4, also would like to connect to P2P1(by user). How can I distinguish between P2P3 as an old peer and P2P4 as a new peer since both of them at the first time only connect() to P2P1(not send() yet)?.
Moreover, I considered to use "hostname:port" to distinguish among them but since they are running on a same machine(hostname is similar), and port is client port(not server port that is unique to every peer, every peer has many client ports). When P2P2 connects to P2P1, P2P1 is informed P2P2 joined the group(including P2P1 and P2P2). When P2P3 connects to P2P2, P2P2 is informed P2P3 joined the group. However, the name of P2P2 at P2P1 is different with the name of P2P2 at P2P3 since client port of P2P2 connecting to P2P1 is different with it of P2P2 connecting to P2P3. I want a unique name for P2P2, how can I do that? Thanks very much for your comment.
Honestly you lost me in your naming scheme.
Let me rephrase the question.
A server accepts two connections. Is there a way to tell that both
connections are initiated by the same agent?
If this is the question you want to be answered, the answer is no. The only information a server has at that moment is what is returned by getpeername, which in your scheme of things doesn't identify the connecting agent.
You may consider assigning each agent a separate range of client ports. Or adding a handshake phase to your protocol.
Background
I am using a SparkCore wireless arduino board to connect to a local Node.js server. The server includes a local intranet TCP server that a TCP client programmed onto the SparkCore connects to.
Problem
If I run the server on a different network, the server has a different local IP address. When I do this, I have to reprogram the SparkCore arduino to tell it the new local IP address of the server to connect its TCP client to. This is not ideal for a variety of reasons.
Question
Is there a way to have the client dynamically search for the TCP server or alternatively have the server broadcast to TCP clients in a way that would inform the client of the local IP address to use for the server without initially hardcoding it? I would love to do this in way that did not involve iterating through a bunch of IPs on a specific port to see if a connection is made. That being said, if that's the only way to do this, then so be it.
How is the arduino booting? If it's booting using DHCP, one method would be to provide a customer DHCP option that provided the address of the node.js server. ntp, for instance, can configure itself in a similar way. This has the advantage that the arduino need not be on the same local subnet as the node.js server.
An alternative (slightly disgusting) would be to use an A record within your domain (let's say nodejs.example.com. Configure the local DNS recursive server to explicitly return this value (I am presuming you might have lots of different deployments with lots of different nodejs servers).
A third possibility would be to send out some form of discovery packet, either by broadcast, or better by multicast UDP. Assuming it's on the same LAN, the nodejs server could then reply. Clearly you might need to concern yourself with a rogue server impersonating your nodejs server, and therefore might need to add some security (e.g. use a shared secret, send a random nonce plus the nonce hashed with the shared secret to the server, the server checks the hash, and replies with the answer, the nonce, plus the answer hashed with the shared secret and the nonce, each of which the client then checks).
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?