I have a client and a server application that is communicating just fine, there is a TIdCmdTCPServer in the server and a TIdTCPClient in the client.
The client has to authenticate in the server, the client asks the server for the newest version information and downloads any updates, and other communications. All this communication with TIdTCPClient.SendCmd() and TIdTCPClient.LastCmdResult.Text.Text.
The way it is, the server receives commands and replies, the clients only receives replies, never commands, and I would like to implement a way to make the client receives commands. But as I heard, if the client uses SendCmd it should never be listening for data like ReadLn() as it would interfere with the reply expected in SendCmd.
I thought of making a command to check for commands, for example, the client would send a command like "IsThereCommandForMe" and the server would have a pool of commands to each client and when the client asks, the server send it in the reply, but I think it would not be a good approach as there would be a big delay between the commands being available and the client asking for it. I also thought of making a new connection with new components, for example a TIdCmdTcpClient, but then there would be 2 connections for each client, I don't like that idea as I think it could easily give problems in the communication.
The reason I want this, is that I want to implement a chat functionality in the client, and it should be receiving messages from the server without asking for it all the time, imagine all clients continually asking the server if there is message for them. And I would like to be able to inform the client when there is an update available instead the client being asking if there is any. And with this I could send more commands to the client too.
what are your thoughts about this ? how can I make the server receiving commands from the clients, but also sends them ?
TCP sockets are bidirectional by design. Once the connection between 'client' and 'server' has been established, they are symmetric and data can be sent at any time from any side over the same socket.
It only depends on the protocol (which is just written 'contract' for the communication) which communication model is used. HTTP for example uses a request/reply model. With Telnet for example, both sides can initate data transmissions. (If you take a look at the Indy implementation for Telnet, you will see that it uses a background thread to listen for server data, but it uses the same socket connection in the main thread to send data from client to server).
A "full duplex" protocol which supports both request/response and server push, and also is firewall-friendly, is WebSockets. With WebSockets (a HTTP upgrade), the server can send data to the connected client(s) any time. This would meet your 'chat' requirement.
If you use TIdTCPClient / TIdCmdTCPServer, corporate firewalls might block the communication.
Related
I am building a browser multiplayer game. For latency, I want to use WebRTC DataChannel to sync the game state. In my setup, one peer is always the server, which is always reachable (no NAT on server side, maybe on user side).
Most setups recommend using a websocket as the signaling channel. I saw some setups with manual copy-pase signaling, with one peer sending an offer to the other peer, the other peer sending an offer back.
Now, this sounds to me like a REST API - Browser does POST request with a SDP offer to the server, then receives SDP answer from server, both can establish connection. When the connection drops, they do that again. Client can always reach server, since that's on a public IP.
What is the disadvantage of doing it this way vs. establishing a websocket and keeping that open?
in a signaling session the SDP is not the only thing you are sending back and forth. So a short answer to why not to use REST API might be that when you trickle ICE candidates other than SDP there are so many messages going back and forth. I believe the SDP only will not have many problems with REST API but overall websocket is preferable basically even just because of websocket faster.
Let's assume there are a several clients that must receive updated data from server. They connect to server and communicate using Server Sent Event push.
How SSE knows that concrete message should be addressed to concrete client like it works in sockets?
Does it support broadcast or private messages?
How SSE knows that concrete message should be addressed to concrete client like it works in sockets?
The client connects to an URL on the server. You can optionally add query parameters to the URL that can be used for logic.
Since the client have initiated the connection, the server must all the time hold a "handle" to this connection, so it can use it to send data. In this way, it is similar to sockets.
Does it support broadcast or private messages?
The server must iterate over all connection handles to send data to all clients. It can send data to only some clients, similar to private messages. How the connections is handled is up to the server.
I developed a client/server application based on sockets.
The client side is in Delphi. The server side is on an IBM I (as400)
Sometimes, the client and the server get disconnected. I'm not really sure why, but I think it's because of a machine between them (a proxy, a router, a firewall) sending a RST packet.
Anyway, I'm trying to reconnect the client with the same process on the server. (not another one, the same, that's important).
To do that, I create a new connection from the client. So, I have two processes on the server. I'll call them the "LostProcess" and the "HelperProcess".
The LostProcess is waiting for data in a data queue.
The client tells the HelperProcess that it was connected to the LostProcess.
The HelperProcess sends data to the LostProcess (via the data queue).
The HelperProcess makes a giveDescriptor, and the LostProcess makes a takeDescriptor.
Then the HelperProcess stops and the LostProcess sends data to the client (to say “I'm back”).
So far, it works, but when the client sends data , the LostProcess (we can call it the RebornProcess now) never receives them (I tried not to stop the HelperProcess, and that he is who receives the data).
With Wireshark, I could see that the client sends data with a different local port, so I guess that's why the RebornProcess does not receive them.
I tried to force the local port of the new client socket to be the same as the first one, but then the new client socket cannot connect for a while, and if I wait long enough, I have the same problem as before.
Does somebody have an idea how to make the reconnection work?
What you are doing is generally not possible. Once a TCP connection has been lost, it is gone forever. Both apps must close their respective sockets for the lost connection, and the client app must create a new socket connection to continue exchanging data with the server.
If the client app wants to reuse the same local port via bind() (which is generally not advisable in most cases), but does not want to wait for the OS to release the port first, then the client can enable the SO_REUSEADDR option via setsockopt() on the new socket before calling bind() and connect().
Pretty sure the answer is you can't.
There'd be all kinds of security issues if TCP/IP allowed a new connection to reconnect to an existing processes connection.
You should have the lost process terminate and just use the new process instead.
I am presently working on a client-server solution to transfer files to another machine via a socket network connection. I am fairly new to the whole client-server thing and therefore have the following - admittedly very basic - question:
For the file transfer, does it make any difference if I am sending the file from a client to a server or from a server to a client?
Any qualified insight into this will be much appreciated!
For the file transfer, does it make any difference if I am sending the file from a client to a server or from a server to a client?
Basically, no it does not matter. Once you have the connection made you are free to send data in both directions. Although you have to consider that a server won't accept data that is sent to it unless it explicitly reads from the socket.
To be a bit more general, server and client are completely arbitrary for a home brewed implementation of data transfer. If you boil this down to the simplest concept then you are just opening a socket and writing data to it on one side, and on the other side you are reading from a different socket.
You might choose to implement a single client program capable of connecting other clients (P2P) and sending files back and forth. In that case you could call the "server" the program that is currently sending the file, and the "client" is the program currently receiving.
Alternatively, you could implement two programs, one for client and one for server. Your server will listen for connections and the client will decide when it wants to connect to the server.
Remember that there are network limitations for connecting. If the program that is listening for connections is behind a firewall then you have to be sure you are forwarding the correct ports. If you are connecting machines within a LAN then you probably have nothing to worry about.
I've been researching memcached, and I'm planning on using that with spymemcached on the client. I'm just curious how client/server communication works between the two. When creating a memcached client object, you can pass in a list of servers, but after the client is created is there any communication between the servers and the client saying that they are still alive and that the client send that particular server information? I've tried looking through the memcached and spymemcached documentation sites, but haven't found anything yet.
Spymemcached does not send any special messages to make sure that the connection is still alive, but you can do this in your application code if necessary by sending no-op messages to each server. You should also note that the TCP layer employs mechanisms such as keep-alive and timeout in order to try to detect dead connections. These parameters however may be different depending on the operating system you are using.