I'm trying to understand how local sockets (Unix domain socket) works, specifically how to use them with QT.
It is my understanding that Unix domain socket is always reliable and no data is lost. Looking at these examples these are the steps (making it simple), considering a Server (producer) and a Client (consumer)..
A qLocalServer (on the Server) create a socket, bind it to a known location and listen for incoming connections..
A qLocalSocket (on the client) connect to the known location. On the server connection is accepted.
Server can send data to the socket using write method (of the qLocalSocket instance returned by qLocalServer->nextPendingConnection())
When the socket buffer is full, any write by the server is blocked as soon as the client read from the socket and free the socket buffer. This is the part I don't understand: suppose the socket buffer is full and the server keeps writing .. where all these data are stored and how to control the data structure holding these data? Is there any way to discard these data?
Imagine a server that produce data 20 times/second and a client that consume 1 time/second, I want to drop all data in bewtween (better real time data than ALL the data in my use case).
There's nothing unique about the Qt socket classes (for the purposes of this question).
When the socket buffer is full, any write by the server is blocked as soon as the client read from the socket and free the socket buffer.
No - the write is blocked until the client performs a read, freeing up some of the buffer. (Perhaps this is what you meant and we just have a minor language barrier.)
Once the server writes to the socket, the data can't be "un-written" so how best to handle this depends on your application, and whether you have more control over the programming of the server or the client.
Related
SSEs are advertised as a unidirectional communication tool to be used from server to client. I have a requirement to broadcast data to all clients and so i was wondering how SSEs behave on a low level. I cannot seem to find any low level information about SSEs online.
Primarily i would like to know if, after sending the data, does the server wait for a response from the client to confirm it has received the data before finishing the "send". That would mean that doing a broadcast using a for loop would be quiet dangerous and slow in which case websockets might be the better options.
Perhaps the implementation depends entirely on the language and framework? Is it not standardized?
Broadcast usually uses UDP which does not wait for a response. - - Broadcasting ip:port by socket server
.. says
UDP Packet: First four bytes as a magic number, next four bytes an IPv4 address (and you might want to add other things like a server name).
The magic number is just in case there is a collision with another application using the same port. Check both the length of the packet and the magic number.
Server would broadcast the packet at something like 30 second time intervals. (Alternatively you could have the server send a response only when a client sends a request via broadcast.)
So the client app would have to send a request back to the server app.
Different protocols would get different responses according the the underlying technology. eg HTTP uses responses extnsivly.
SSE and WebSockets are both over TCP, so there could be a wait before the socket could be used to send further data.
However, each client is a dedicated socket. So server-side you would be using threads or async coding (depending on the server-side language and its conventions). So looping through all the sockets to send a message to each client would be fine and quick.
I write a simple server application. In that application, I created a server socket and put it into the listen state with listen call.
After that, I did not write any code to accept the incoming connection request. I simply waited for the termination with pause call.
I want to figure out practically that how many bytes are buffered in the server side if the connection is not accepted. Then I want to validate the number with the theory of the TCP.
To do that,
First, I started my server application.
Then I used "dd" and "netcat" to send the data from client to server. Here is the command:
$> dd if=/dev/zero count=1 bs=100000 | nc 127.0.0.1 45001
Then I opened wireshark and wait for the zero-window message.
From the last properly acknowledged tcp frame. the client side can successfully send 64559 byte data to the server.
Then I execute the above dd-netcat command to create another client and send data again.
In this case, I got the following wireshark output:
From the last successfully acknowledged tcp frame, I understand that the client application can successfully sent 72677 bytes to the server.
So, it seems that the size of the related buffer can change in runtime. Or, I misinterpret the output of the wireshark.
How can I understand the size of the related receive buffer? What is the correct name to refer that receive buffer in terminology? How can I show the default size of the related receive buffer?
Note that the port number of the tcp server is "45001".
Thank you!
I have some data aquisition devices in industrial machinery that have 4G connectivity. Right now I make them to stream the intrumentation data in real time to my server through raw TCP/IP protocol. But this has some problems:
The machinery sometimes work in places where there is low or null mobile connectivity. If there is no connectivity for too long it can happen two things: a) the machine gets shutted down and the tcp/ip buffer it's lost along with the instrumentation data or b) the tcp/ip buffer overflows, which has the same results.
The same as point 1, but for the server side, due to maintenance or if something in the server fails in the weekend when nobody is going to notice it but the machinery can be ON and working. Then we can have data loss in the same way as point 1.
I have to manage authentication and the connection of all the clients into a server single TCP port. I have done some temporary hack that works for the moment but isn't the best. But this is another problem and it's not the reason of this question, so take it only for context.
So, I should code an application layer acknowledge where the server tells the client when a high-level message (not the individual TCP packets) has been received and processed. And in the client side to have a buffer writted in-disk where data is being deleted as is being confirmed by the server. This, to solve points 1 & 2.
But I'm afraid that I'm reinventing the wheel or that I don't know the correct tools, because I think that this problem should be more or less common but I fail to google for it and I can't find a library or tool that does this job.
What I was thinking about is something that in the remote client is listenning in a local TCP port for incomming data from the DAQ software, once it receives a message it streams it to the server and writes it to the local disk. In the server, the tool receives the message and re-streams it over local network to the final server. Then, notifies the client that is able to delete the message from its disk buffer.
So, the question is, there is something already done? I would prefer an already compiled / language agnostic solution because I code in LabView and I know there isn't like that in its ecosystem, but I'm open to everything. If there isn't anything like that, any advice in what to do / to avoid when developing it myself?
Thanks for your time.
I have a TCP client server application written on boost 1.53. Based on the client command I have to start a server thread to write some data to a socket. But I have no guarantee that the client application would start reading from this socket.
Is there any trouble writing data to a socket without reading from it? Won't be there any socket overflow or data corruption ?
Looking forward to hearing your ideas.
Thx,
Dmitry
What happens when sending data to a slow or non-cooperative remote side is covered by the flow control aspect of TCP.
Suppose you try to send data and the application in the remote side refuses to read it. Eventually the remote side's receive window becomes full, and it will indicate this by sending an ACK with a window size 0. Your network stack stops trying send new packets until an ACK with a larger window size is received. If you keep trying to send data it accumulates in the send buffer in your network stack. When the buffer becomes full writing to your side of the socket blocks.
Using TCP, that won't be a problem. The server will detect that the client isn't reading, and hold off on sending more data until the client has acknowledged receipt of the already-sent data. In this case the server thread will block until the client is ready to accept more data.
Also TCP packets are checksummed, so if any get corrupted in transit the client will reject them and the server will resend them.
I am trying to get a handle on what happens when a server publishes (over tcp, udp, etc.) faster than a client can consume the data.
Within a program I understand that if a queue sits between the producer and the consumer, it will start to get larger. If there is no queue, then the producer simply won't be able to produce anything new, until the consumer can consume (I know there may be many more variations).
I am not clear on what happens when data leaves the server (which may be a different process, machine or data center) and is sent to the client. If the client simply can't respond to the incoming data fast enough, assuming the server and the consumer are very loosely coupled, what happens to the in-flight data?
Where can I read to get details on this topic? Do I just have to read the low level details of TCP/UDP?
Thanks
With TCP there's a TCP Window which is used for flow control. TCP only allows a certain amount of data to remain unacknowledged at a time. If a server is producing data faster than a client is consuming data then the amount of data that is unacknowledged will increase until the TCP window is 'full' at this point the sending TCP stack will wait and will not send any more data until the client acknowledges some of the data that is pending.
With UDP there's no such flow control system; it's unreliable after all. The UDP stacks on both client and server are allowed to drop datagrams if they feel like it, as are all routers between them. If you send more datagrams than the link can deliver to the client or if the link delivers more datagrams than your client code can receive then some of them will get thrown away. The server and client code will likely never know unless you have built some form of reliable protocol over basic UDP. Though actually you may find that datagrams are NOT thrown away by the network stack and that the NIC drivers simply chew up all available non-paged pool and eventually crash the system (see this blog posting for more details).
Back with TCP, how your server code deals with the TCP Window becoming full depends on whether you are using blocking I/O, non-blocking I/O or async I/O.
If you are using blocking I/O then your send calls will block and your server will slow down; effectively your server is now in lock step with your client. It can't send more data until the client has received the pending data.
If the server is using non blocking I/O then you'll likely get an error return that tells you that the call would have blocked; you can do other things but your server will need to resend the data at a later date...
If you're using async I/O then things may be more complex. With async I/O using I/O Completion Ports on Windows, for example, you wont notice anything different at all. Your overlapped sends will still be accepted just fine but you might notice that they are taking longer to complete. The overlapped sends are being queued on your server machine and are using memory for your overlapped buffers and probably using up 'non-paged pool' as well. If you keep issuing overlapped sends then you run the risk of exhausting non-paged pool memory or using a potentially unbounded amount of memory as I/O buffers. Therefore with async I/O and servers that COULD generate data faster than their clients can consume it you should write your own flow control code that you drive using the completions from your writes. I have written about this problem on my blog here and here and my server framework provides code which deals with it automatically for you.
As far as the data 'in flight' is concerned the TCP stacks in both peers will ensure that the data arrives as expected (i.e. in order and with nothing missing), they'll do this by resending data as and when required.
TCP has a feature called flow control.
As part of the TCP protocol, the client tells the server how much more data can be sent without filling up the buffer. If the buffer fills up, the client tells the server that it can't send more data yet. Once the buffer is emptied out a bit, the client tells the server it can start sending data again. (This also applies to when the client is sending data to the server).
UDP on the other hand is completely different. UDP itself does not do anything like this and will start dropping data if it is coming in faster then the process can handle. It would be up to the application to add logic to the application protocol if it can't lose data (i.e. if it requires a 'reliable' data stream).
If you really want to understand TCP, you pretty much need to read an implementation in conjunction with the RFC; real TCP implementations are not exactly as specified. For example, Linux has a 'memory pressure' concept which protects against running out of the kernel's (rather small) pool of DMA memory, and also prevents one socket running any others out of buffer space.
The server can't be faster than the client for a long time. After it has been faster than the client for a while, the system where it is hosted will block it when it writes on the socket (writes can block on a full buffer just as reads can block on an empty buffer).
With TCP, this cannot happen.
In case of UDP, packets will be lost.
The TCP Wikipedia article shows the TCP header format which is where the window size and acknowledgment sequence number are kept. The rest of the fields and the description there should give a good overview of how transmission throttling works. RFC 793 specifies the basic operations; pages 41 and 42 details the flow control.