How to use publish data over TCP socket instead of UDP - sockets

I have been trying to to use pubnub in order to sent data stream through peers. What is happening though is that the message size on the one side is different from the one the other, though the number of messages sent and received are the same.What i have in mind is that by somehow part of the packets are lost
pubnub.publish({
channel: 'my_channel',
'message' : {
'packet': array_of_packets[counter_array_of_packets],
'which_packet_is': counter_array_of_packets,
'payload_size': calculate_payload_size('my_channel'array_of_packets[counter_array_of_packets])
}
callback : function(m){console.log(m)}
});
pubnub.subscribe({
channel: 'my_channel',
message: function(m){wait_(m)},
uuid: 'Mitsos',
error: function (error) {
// Handle error here
console.log(JSON.stringify(error));
}
});
The function used to calculate the size is:
function calculate_payload_size( channel, message ) {
return encodeURIComponent(
channel + JSON.stringify(message)
).length + 100;
}
So how can i use the above two functions publish and subscribe in a way that the TCP (reliable transmitting) is used?
(if this can be of any help here is implemented a working example of pubnub - index.html where packets reach the right way the other side, though i can't seem to find if he uses tcp anywhere link)

All PubNub client libraries communicate over a TCP socket connection only.
If you are using PubNub JavaScript, Java or Objective-C SDK, then the SDK will take care of Keeping the TCP Socket Connection open for you automatically after you have subscribed to a data channel. This guide on http-streaming-over-tcp-with-telnet-example will provide an easy way to use Telnet as an example of Streaming your JSON message payloads over TCP socket.
You can keep a TCP Socket active and alive forever with PubNub's unlimited TTL Socket Session Policy by writing an initial data payload over the socket. After you've established the TCP connection, send an initial payload. Watch this video on Keeping a TCP Socket Connection Open on your first Network Call which walks you through the steps of how to keep a TCP socket connection open.

Related

I can not sent short messages by TCP protocol

I have a trouble to tune TCP client-server communication.
My current project has a client, running on PC (C#) and a server,
running on embedded Linux 4.1.22-ltsi.
Them use UDP communication to exchanging data.
The client and server work in blocking mode and
send short messages one to 2nd
(16, 60, 200 bytes etc.) that include either command or set of parameters.
The messages do note include any header with message length because
UDP is message oriented protocol. Its recvfrom() API returns number of received bytes.
For my server's program structure is important to get and process entire alone message.
The problem is raised when I try to implement TCP communication type instead of UDP.
The server's receive buffer (recv() TCP API) is 2048 bytes:
#define UDP_RX_BUF_SIZE 2048
numbytes = recv(fd_connect, rx_buffer, UDP_RX_BUF_SIZE, MSG_WAITALL/*BLOCKING_MODE*/);
So, the recv() API returns from waiting when rx_buffer is full, i.e after it receives
2048 bytes. It breaks all program approach. In other words, when client send 16 bytes command
to server and waits an answer from it, server's recv() keeps the message
"in stomach", until it will receive 2048 bytes.
I tried to fix it as below, without success:
On client side (C#) I set the socket parameter theSocket.NoDelay.
When I checked this on the sniffer I saw that client sends messages "as I want",
with requested length.
On server side I set TCP_NODELAY socket option to 1
int optval= 1;
setsockopt(fd,IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval);
On server side (Linux) I checked socket options SO_SNDLOWAT/SO_RCVLOWAT and they are 1 byte each one.
Please see the attached sniffer's log picture. 10.0.0.10 is a client. 10.0.0.106 is a server. It is seen, that client activates PSH flag (push), informing the server side to move the incoming data to application immediately and do not fill a buffer.
Additional question: what is SSH encrypted packets that runs between the sides. I suppose that it is my Eclipse debugger on PC (running server application through the same Ethernet connection) sends them. Am I right?
So, my problem is how to cause `recv() API to return each short message (16, 60, 200 bytes etc.) instead of accumulating them until receiving buffer fills.
TCP is connection oriented and it also maintains the order in which packets are sent and received.
Having said that, in TCP client, you will receive the stream of bytes and not the individual udp message as in UDP. So you will need to send the packet length and marker as the initial bytes.
So client can first find the packet length and then read data till packet length is reached and then expect new packet length.
You can also check for library like netty, zmq to do this extra work

Using "send" to tcp socket/Windows/c

For c send function(blocking way) it's specified what function returns with size of sent bytes when it's received on destinations. I'm not sure that I understand all nuances, also after writing "demo" app with WSAIoctl and WSARecv on server side.
When send returns with less bytes number than asked in buffer-length parameter?
What is considered as "received on destinations"? My first guess it's when it sit on server's OS buffer and server application is notified. My second one it's when server application recv call have read it fully?
Unless you are using a (somewhat exotic) library, a send on a socket will return the number of bytes passed to the TCP buffer successfully, not the number of bytes received by the peer (see Microsoft´s docs for example).
When you are streaming data via a socket, you need to check the bytes effectively accepted into the TCP send buffer. That´s why usually a send command is inside a loop that will issue several sends if needed.
Errors in send are local: for example if the socket is closed by the peer during a sending operation (making your socket invalid) or if the operation times out (TCP buffer not emptying, i. e. peer not receiving data fast enough or some other trouble).
After all send is completed you have no easy way of knowing if the peer received all the bytes you sent. You´ll usually just issue closesocket and make sure that your socket has a proper linger option set (i. e. only close after timeout or sucessfully finishing the send). Alternatively you wait for a confirmation by the peer (for example via a recv that returns zero bytes, indicating that the connection was gracefully closed).
Edit: typo

Can another client app close TCP connection which a crashed client app opened with a server?

Consider the following sequence:
Client app (web browser) opens several TCP connections to different web servers;
Ethernet cable then becomes disconnected;
Client app is then closed;
Ethernet cable remains disconnected for a few hours;
Ethernet cable is reconnected;
I see "TCP keep-alive" packets (every 60 seconds, for hours) from a few of the servers to which the long-closed client app had connected!
Normally, when an app is closing, the app would initiate the closure of each open socket, and the TCP layer would then attempt to send a FIN packet to each remote endpoint. If it is physically possible to send the FIN packet, and such sending actually happens, then the local endpoint goes from the ESTABLISHED state to the FINWAIT_1 state (and awaits receiving an ACK from the remote endpoint, etc.). But, if the physical link is broken, then the TCP local endpoint can't send that FIN, and the server still assumes the TCP connection still exists (and the client-side call to the "close" function would block indefinitely until the physical link was reestablished, assuming the socket were set to blocking mode, right?).
In any case, upon reconnecting the Ethernet cable after some time with all conventional networked apps (e.g., web browsers) long closed, I am receiving "TCP Keep-Alive" packets from three separate web servers at precisely 60-second intervals for HOURS!
Wireshark shows the local port numbers to which these TCP Keep-Alive packets are being sent, but neither TCPView nor netstat -abno show those local port numbers being used by any application. Looking at the "TCP/IP" property of every single running process using Process Explorer also does not show any matching port numbers. I don't think the ports are being held because of a zombie "process record" (of, say, the web browser process) due to any ongoing child process (e.g., plugin app), but I'm not sure if my observations with TCPView/netstat/Process Explorer were sufficient to rule out this possibility.
Given the identities of the remote web servers (e.g., Akamai servers), I believe the connections were established by "recent" use of a web browser. But, these keep-alives keep coming from those three web servers, even though the browser had been closed, and the physical link had been broken for hours.
If the connections appeared in TCPView, I could simply select them and manually close them. However, the client-side TCP endpoints seem long gone.
Meanwhile, I am baffled why the servers are retrying so many times to get a reply to their keep-alive packets.
TCP keep-alive behavior is typically controlled by three parameters: \
(1) Time to wait until the next "burst" or "probe" attempts;
(2) Time interval between sending each keep-alive packet during a single "probe" attempt;
(3) The maximum number of "probe" attempts before the "burst" is considered a failure (and the TCP connection is consequently considered permanently broken).
For the TCP keep-alive packets I am seeing from the three different servers, the time interval between "probe" retries is exactly 60 seconds. But, it seems like the maximum number of "probe" retries is infinite, which seems like a really bad choice for any server!
Although I am curious about how this relentless stream of keep-alives was created and sustained, I am more immediately interested in how I might use a client-side application to force the server-side endpoints to close, given that there aren't existing local TCP endpoints receiving those keep-alive packets.
My rough idea is to create an app which creates a TCP-mode socket, binds (with port-number reuse allowed) to the port number to which the incoming keep-alives are directed, and then call "open" followed by "close", hoping that the server endpoint will make the TCP state transitions to reach the closed state one way or another! Another way might be to create a raw-mode socket, and receive the TCP keep-alive packet (which is just an ACK), and then form and send an appropriate FIN packet (with proper sequence number, etc., to pick up where the long-terminated client app evidently left off), and then receive an ACK and FIN before sending the final ACK.
One final note -- and I know there will be eye-rolling and ridicule: the working environment here is Windows XP SP3 running in VirtualBox on Windows 7! So, I'd prefer code or an open-source app which could achieve the goal (closing half-open TCP connection) within Windows XP SP3. Sure, I could restart the snapshot, which might close the connections -- but I am more interested in learning how to get more information about the state of network connections, and what I can do to handle this kind of TCP state problem.
I succeeded in provoking the closing of each apparent half-open TCP connection by writing a simple program (full code appears below) which binds a local socket to the port to which the server believes it is already connected, attempts to establish a new connection, and then closes the connection.
(Note: If the connection succeeds, I make an HTTP GET request, just because the phantom TCP keep-alives in my case are apparently originating from plain HTTP servers, and I was wondering what response I might get back. I think the "send" and "recv" calls could be removed without affecting the ability of the code to achieve the desired result.)
In the following code, the src_port_num variable represents the client-side port number (currently unused) to which the server is sending "TCP keep-alive" packets, and dst_ip_cstr is the IP address of the server (e.g., an Akamai web server), and dst_port_num is the port number (which, in my situation, happens to be a plain HTTP server at port 80).
CAUTION! By sharing this code I do not mean to imply that its theory of operation can be rigorously explained by an understanding of the TCP protocol specification. I just guessed that claiming an abandoned local port to which a remote endpoint is sending TCP keep-alive packets, and attempting to establish a new connection to that very same remote endpoint, would, one way or another, prod the remote endpoint to close the stale half-open connection -- and it happened to work for me.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
void main()
{
// Local IP and port number
char * src_ip_cstr = "10.0.2.15";
int src_port_num = 4805;
// Remote IP and port number
char * dst_ip_cstr = "23.215.100.98";
int dst_port_num = 80;
int res = 0;
WSADATA wsadata;
res = WSAStartup( MAKEWORD(2,2), (&(wsadata)) );
if (0 != res) { printf("WSAStartup() FAIL\n"); return; }
printf( "\nSRC IP:%-16s Port:%d\nDST IP:%-16s Port:%d\n\n",
src_ip_cstr, src_port_num, dst_ip_cstr, dst_port_num );
sockaddr_in src;
memset( (void*)&src, 0, sizeof(src) );
src.sin_family = AF_INET;
src.sin_addr.S_un.S_addr = inet_addr( src_ip_cstr );
src.sin_port = htons( src_port_num );
sockaddr_in dst;
memset( (void*)&dst, 0, sizeof(dst) );
dst.sin_family = AF_INET;
dst.sin_addr.S_un.S_addr = inet_addr( dst_ip_cstr );
dst.sin_port = htons( dst_port_num );
int s = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
if ((-1) == s) { printf("socket() FAIL\n"); return; }
int val = 1;
res = setsockopt( s, SOL_SOCKET, SO_REUSEADDR,
(const char*)&val, sizeof(val) );
if (0 != res) { printf("setsockopt() FAIL\n"); return; }
res = bind( s, (sockaddr*)&src, sizeof(src) );
if ((-1) == res) { printf("bind() FAIL\n"); return; }
res = connect( s, (sockaddr*)&dst, sizeof(dst) );
if ((-1) == res) { printf("connect() FAIL\n"); return; }
char req[1024];
sprintf( req, "GET / HTTP/1.1\r\nHost: %s\r\nAccept: text/html\r\n"
"Accept-Language: en-us,en\r\nAccept-Charset: US-ASCII\r\n\r\n",
dst_ip_cstr );
printf("REQUEST:\n================\n%s\n================\n\n", req );
res = send( s, (char*)&req, strlen(req), 0 );
if ((-1) == res) { printf("send() FAIL\n"); return; }
const int REPLY_SIZE = 4096;
char reply[REPLY_SIZE];
memset( (void*)&reply, 0, REPLY_SIZE );
res = recv( s, (char*)&reply, REPLY_SIZE, 0 );
if ((-1) == res) { printf("recv() FAIL\n"); return; }
printf("REPLY:\n================\n%s\n================\n\n", reply );
res = shutdown( s, SD_BOTH );
res = closesocket( s );
res = WSACleanup();
}
HILARIOUS / SHAMEFUL / FASCINATING DISCLOSURES
As I mentioned in my original question, I observed these "TCP keep-alive" packets with Wireshark within VirtualBox running Windows XP SP3, where the host OS was Windows 7.
When I woke up this morning and looked at the phenomenon again with a cup of coffee and fresh eyes, with the "TCP keep-alive" packets still appearing every 60 seconds even after 24 hours, I made a hilarious discovery: These packets continued to arrive from the three different IP addresses, precisely at 60-second intervals (but staggered for the three IPs), even when I disconnected the Ethernet cable from the Internet! My mind was blown!
So, although the three IP addresses did correspond to real-world web servers to which my web browser connected long ago, the TCP keep-alive packets were clearly originating from some local software component.
This revelation, as shocking as it was, did not change my thinking about the situation: from my client-side software perspective, there were "server-side" half-open TCP connections that I wanted to provoke to closing.
Within VirtualBox, choosing "Devices" -> "Network" -> "Connect Network Adapter" toggles the virtual network adapter on or off, as if a virtual Ethernet cable were connected or disconnected. Toggling to a disconnected state caused the phantom TCP keep-alive packets to stop arriving to Wireshark. Subsequently toggling to a connected state caused the TCP keep-alive packets to resume arriving in Wireshark.
Anyway, I sometimes needed to run the code above TWICE to succeed in closing the half-open connection. When running the code a first time, Wireshark would show a packet with an annotation "[TCP ACKed unseen segment]", which is just the kind of TCP gas-lighting confusion I hoped to create, haha! Because the new client endpoint is unexpected by the remote endpoint, the call to "connect" hangs for maybe 30 seconds before failing. For a couple of the zombie/phantom half-open connections, running the program just once was enough to also cause an RST packet.
I needed to modify the program repeatedly to change the combination of local port number, remote IP, and remote port number, to match each phantom TCP keep-alive packet I observed in Wireshark. (I leave implementing user-friendly command-line parameters to the dear reader (that's you!).) After a few rounds of modifying and running the program, all zombie keep-alive packets were stopped. "Silence of the Packets", one might say.
EPILOGUE
[In tuxedo, martini glass in hand, gazing wistfully at the ocean from the deck of a yacht, in the company of fellow hackers] "I never did figure out where those zombie packets came from... Was it the 'VirtualBox Host-Only Network' virtual Ethernet adapter? Only the Oracle knows!"
There is nothing you need to do to close the remote socket, it is already built into the TCP protocol. If the system receives TCP packets which don't create a new connection (i.e. have SYN set) and don't belong to any established connection, it will reply with a RST packet. This way the peer will know that the endpoint is no longer there and abandon the connection.

Processing of a TCP packet

I am wondering what is happening between the creating a TCP packet and a [Ethernet[IP[TCP-packet]]] leaving the network adapter.
When i use for example a TCP program and want to send a single packet ( or could be more in fact TCP using byte streaming).
So i set up in any language a function called socket(...);
So my OS, refering to any documenation, creating me an interface with a specified port on which I can receive and send data over.
And if I create a TCP package (for example sendto(...), it will be send to the socket.
But what kind processes are done now [1], until my packet will leave the network adapter with an Ethernet + IP Header?
[1]: Where are the following steps happening (OS/Network adapter) and how does it exactly work?
Hope you understand me.. and please correct me if I missunderstood something wrong.

Time Gap Between Socket Calls ie. Accept() and recv/send calls

I am implementing a server in which i listen for the client to connect using the accept socket call.
After the accept happens and I receive the socket, i wait for around 10-15 seconds before making the first recv/send call.
The send calls to the client fails with errno = 32 i.e broken pipe.
Since i don't control the client, i have set socket option *SO_KEEPALIVE* in the accepted socket.
const int keepAlive = 1;
acceptsock = accept(sock, (struct sockaddr*)&client_addr, &client_addr_length)
if (setsockopt( acceptsock, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(keepAlive)) < 0 )
{
print(" SO_KEEPALIVE fails");
}
Could anyone please tell what may be going wrong here and how can we prevent the client socket from closing ?
NOTE
One thing that i want to add here is that if there is no time gap or less than 5 seconds between the accept and send/recv calls, the client server communication occurs as expected.
connect(2) and send(2) are two separate system calls the client makes. The first initiates TCP three-way handshake, the second actually queues application data for transmission.
On the server side though, you can start send(2)-ing data to the connected socket immediately after successful accept(2) (i.e. don't forget to check acceptsock against -1).
After the accept happens and I receive the socket, i wait for around 10-15 seconds before making the first recv/send call.
Why? Do you mean that the client takes that long to send the data? or that you just futz around in the server for 10-15s between accept() and recv(), and if so why?
The send calls to the client fails with errno = 32 i.e broken pipe.
So the client has closed the connection.
Since I don't control the client, i have set socket option SO_KEEPALIVE in the accepted socket.
That won't stop the client closing the connection.
Could anyone please tell what may be going wrong here
The client is closing the connection.
and how can we prevent the client socket from closing ?
You can't.