Forward all data over a QTcpSocket - qt

I have a ssh tunnel setup using libssh. However, this does not bind it to a local port, so what I need essentially is to forward all data received on a port to the ssh channel. However, when I do this:
QTcpSocket* socket = new QTcpSocket();
socket->bind(27017);
QObject::connect(socket, &QTcpSocket::readyRead, this, &Forwarder::newData);
The newData slot is never invoked i.e. the readyRead on QTcpSocket is never invoked. Whenever I try to connect to the port via an external script, I get an Operation timed out. I am sure that atleast the port is opened because when the Qt application is not running, the error I get is Connection refused.
I have considered using QTcpServer, however, how do I even handle this case? I will probably get newConnection signals, but what data do I write to the ssh channel? How would I handle multiple incoming connections for a QTcpServer? Isn't a connection request also a data packet? Can I just not forward everything to the channel (The ssh channel I am referring to is akin to a fd that I can simple write to).

Related

write before read with Arduino Ethernet library

A tcp server is implemented on the arduino using EthernetServer(port), a connection is accepted using
client = server.available();
if (client) {
...
}
However, as far as I understand the source of available correctly, it returns a valid client only when there is something to read from this client object.
But I want to send a kind of greeting and a prompt as soon as the connection is established, so, before something has been sent to the connection from the remote side.
Who can I achieve that?

Recover port from Boost Asio udp::endpoint

I am programming a server and client program to communicate between a windows PC using the Boost libraries and a Linux ARM beagleboard using the asio stand alone libraries. I have for a while had successful UDP communication between the two devices but now I want to recover the port from the endpoint the server discovers when the client connects. The way the client connects is via query:
udp::resolver resolver(io_service);
udp::resolver::query query_tx(udp::v4(), hostIP, "43210");
udp::endpoint receiver_endpoint_tx = *resolver.resolve(query_tx);
where host IP is a string and this works fine. Upon debugging though I notice that when i check the value returned by:
receiver_endpoint_tx.port()
This returns 51880. Now don't jump the guns and yell out network byte order and host byte order. I AM AWARE. The strange part is that this number 51880 sometimes is a different number and when i check what the server has stored in its endpoint it is a completely different number: 21743. Now I know I must be doing something wrong with the byte orders but i tried:
//unsigned long port_long = boost::asio::detail::socket_ops::host_to_network_long(receiver_endpoint_tx.port());
//unsigned long port_short = boost::asio::detail::socket_ops::host_to_network_short(receiver_endpoint_tx.port());
And they do not give me back my original port: 43210. Neither does network to host. So what am i missing and how can I on both ends recover my 43210 port? Obviously it must be there somewhere because they are successfully communicating.
Thanks in advance, sorry if noob mistake :)
Fistly, UDP is connectionless, there is no connection.
I'm not sure if I understand you correctly, but it sound too me like you want to bind to specific port numbers. If you want the client to send a packet from port x to port y on the server, and the server should respond from port y to port x, then you need to bind the sockets to the desired ports. Alternatively you can use the constructor to bind. Not doing so will result in the OS using ephemeral ports.
Further, to get the remote endpoint that a packet was received from the async_receive_from takes the sender_endpoint reference parameter. When the read handler is called, you can retrieve host and port from it.

Sending packets via UDP in erlang

so i'm trying to send udp packet to a listening port on a computer which is not connected to the same LAN but has internet access via gen_udp in erlang.
I start my first node by opening the port
({ok, Socket} = gen_udp:open(8887).) and the open the port on the other node the same way, When i send a packet from one node to the other via gen_udp:send i don't receive anything (trying flush() on the receiving node), So i'm wondering if there is something i'm doing wrong ? , i checked the firewalls and erlang and epmd is permitted.
did you try setting the controlling process of the Socket as the current process via :
gen_udp:controlling_process(Socket,Pid) ?
You should then setup a receive loop and messages will be sent to you. The format of the messages should be : {udp, Socket, IP, InPortNo, Packet}
You could also try setting the socket to passive mode by using inet:setopts(Socket, [{active, false}]) after you have opened it. After which you can use 'gen_udp:recv/3` to read from the socket.

Disconnect and Reconnect a connected datagram socket

Iam trying to create an iterative server based on datagram sockets (UDP).
It calls connect to the first client which it gets from the first recvfrom() call (yes I know this is no real connect).
After having served this client, I disconnect the UDP socket (calling connect with AF_UNSPEC)
Then I call recvfrom() to get the first packet from the next client.
Now the problem is, that the call of recvfrom() in the second iteration of the loop is returning 0. My clients never send empty packets, so what could be going on.
This is what Iam doing (pseudocode):
s = socket(PF_INET, SOCK_DGRAM, 0)
bind(s)
for(;;)
{
recvfrom(s, header, &client_address) // get first packet from client
connect(s,client_address) // connect to this client
serve_client(s);
connect(s, AF_UNSPEC); // disconnect, ready to serve next client
}
EDIT: I found the bug in my client accidently sending an empty packet.
Now my problem is how to make the client wait to get served instead of sending a request into nowhere (server is connected to another client and doesn't serve any other client yet).
connect() is really completely unnecessary on SOCK_DGRAM.
Calling connect does not stop you receiving packets from other hosts, nor does it stop you sending them. Just don't bother, it's not really helpful.
CORRECTION: yes, apparently it does stop you receiving packets from other hosts. But doing this in a server is a bit silly because any other clients would be locked out while you were connect()ed to one. Also you'll still need to catch "chaff" which float around. There are probably some race conditions associated with connect() on a DGRAM socket - what happens if you call connect and packets from other hosts are already in the buffer?
Also, 0 is a valid return value from recvfrom(), as empty (no data) packets are valid and can exist (indeed, people often use them). So you can't check whether something has succeeded that way.
In all likelihood, a zero byte packet was in the queue already.
Your protocol should be engineered to minimise the chance of an errant datagram being misinterpreted; for this reason I'd suggest you don't use empty datagrams, and use a magic number instead.
UDP applications MUST be capable of recognising "chaff" packets and dropping them; they will turn up sooner or later.
man connect:
...
If the initiating socket is not connection-mode, then connect()
shall set the socket’s peer address, and no connection is made.
For SOCK_DGRAM sockets, the peer address identifies where all
datagrams are sent on subsequent send() functions, and limits
the remote sender for subsequent recv() functions. If address
is a null address for the protocol, the socket’s peer address
shall be reset.
...
Just a correction in case anyone stumbples across this like I did. To disconnect connect() needs to be called with the sa_family member of sockaddr set to AF_UNSPEC. Not just passed AF_UNSPEC.

Wavecom GSM modem as a TCP client

I've been trying to do TCP communication using my Wavecom Fastrack modem. What I want to achieve is make the modem connect to a specified TCP server port to enable me to transfer data to and from the server. I found some information on than in the user's guide.
Basing on the information you can find on page 66 I created an application that opens the serial port to which the modem is connected and writes the following AT commands:
AT+WIPCFG=1 //start IP stack
AT+WIPBR=1,6 //open GPRS bearer
AT+WIPBR=2,6,11,"APN" //set APN of GPRS bearer
AT+WIPBR=2,6,0 //username
AT+WIPBR=2,6,1 //password
AT+WIPBR=4,6,0 //start GPRS bearer
AT+WIPCREATE=2,1,"server_ip_address",server_port //create a TCP client on port "server_port"
AT+WIPDATA=2,1,1 //switch do data exchange mode
This is exactly what the user's guide says. After the last command is sent to the modem, the device switches to data exchange mode and from then on everything what is written to the serial port opened by my application should be received by the server and everything the server sends should appear in the input buffer of that port.
The thing is that I did not manage to maintain stable bidirectional communication between the server and my modem. When I write some data to the serial port (only a few bytes), it takes a lot of time before the data appears on the server's side and in many cases the data does not reach the server at all.
I performed a few tests writing about 100 bytes to the serial port at once. Logging the data received by my server application I noticed that the first piece of data (8-35 bytes) is received after a second or two. The rest of the data appears in 2-5 seconds (either as a whole or in pieces of the said size) or does not appear at all.
I do not know where to look for the reason of that behaviour. Did I use wrong AT commands to switch the modem to TCP client mode? I can't believe the communication may be so slow and unstable.
Any advice will be appreciated. Thank you in advance.
what OS are you running? Windows does a pretty good job of hiding the messy details of communicating with the GPRS modem, all you have to do is create a new dial-up connection. To establish the connection you can make a call to the Win32 RasDial function. Once connected, you can use standard sockets to transfer data on a TCP port.
i have been using wavecomm modem for 2 years now.As far as i know from my experience is that if you are able to send some of the data then you can send all of the data.
the problem might be in the listening application which receives the data on the server side.
It could be that it is unable to deal with the amount of data that you are trying to send.
try sending the same data in smaller busts
with some delay in between them,then you might receive all data intact.

Resources