SIM900D Transparent Mode to Webserver permits only to transmit once - tcp

I used this series of AT commands to be able to connect and transmit/receive data with my laptop via the SIM900D GSM/GPRS module.
https://stackoverflow.com/questions/2...icrocontroller
The TCP connection does not end not until either of the two endpoints decided to terminate the TCP connection.. On the other hand, when I tried to connect with our webserver (e.g. AT+CIPSTART="TCP","www.mydomain.com","80")
It achieves connection.. But if the GPRS module does not immediately send any data, soon the webserver terminates the TCP connection.. If I tried sending by sending the url (e.g. PUT /send.php?g0=21 HTTP/1.1\r\nHost: dlsu-ect.com\r\n\r\n$1A\r), the webserver receives the data but it ends the terminate right after that transmission. Transparent mode only permit one transmission per TCP connection..
Am I doing it right? Is my way of transmitting the data to our webserver the right way for transparent mode?

If your request is correctly saving data to the server, you can try to add a header which requests that the server does not close the connection immediately after responding to the first request.
Try sending:
PUT /send.php?g0=21 HTTP/1.1\r\n
Host: dlsu-ect.com\r\n
Connection: Keep-alive\r\n
Content-length: 3\r\n
\r\n
$1A\r\n
\r\n
That should keep your connection alive, depending on the server configuration. As some servers do not allow keep-alive connections this might not work. You could also test keep-alive using telnet before attempting to do it on your Sim900 right away.
Also note that the timeout between requests differs a lot between servers. Some only allow a few seconds between requests.

Related

Firebase - Switching to WebSocket protocol - handshake not working

I'm using ESP-01/ESP8266 Wifi module to make SSL connection to my google firebase project.
I'm already able to write/read to/from the database using HTTP protocol and REST API, and my next goal is to switch the protocol to WebSocket, in order the server and client (my board) can speak this protocol after the initial handshake. Currently I'm not even making the handshking to work, and this is the point I'm currently stuck.
What I tried so far:
(1) First, I open TCP socket with SSL, connect to wss://eletronica-ab6b1.firebaseio.com, port 443. The SSL steps are being done by the wifi module, SSL/TLS is one of its features.
(2) After connection is up, I send the following HTTP packet to the server, actually is only a HTTP header, without data. Packet:
GET /January HTTP/1.1
Host: eletronica-ab6b1.firebaseio.com
Upgrade: Websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
This is the response of the server:
Why I used "January"? Check, this is my database:
What do I need to change in order to work? I mean in terms of content of the headers and also the connection to the domain.
Regards.
EDIT:
My final goal is: the board stablish a constant TCP connection to firebase server. When a value of the database be changed, the board will be notified by the server through the protocol, so there will be no need of the board to stay polling the server (each X seconds) to know if the value was changed. Am I on the right way to reach this? Using WebSocket protocol?
I've never tried it but you could find a way to achieve something similar to websockets using gRpc https://firebase.google.com/docs/firestore/reference/rpc/

How to check http(s) request connection status?

Story: In a client-server system I use a long time connection(an http(s) request from client to server with a long time timeout) in order to use notify client to do some actions(Most of data transfer is from client to server but some commands send to client in response of this http(s) request).
Problem: If client cancel the connection server can understand that but if internet connection of client loses(e.g, unplug the LAN cable or it loses the WLAN/GPRS antenna) neither client nor server understand this. Connection still remains until (some time spends and) somebody writes something in it which is too late.
PS: 0) I googled with AKC/NACK, Keep-alive, ping-pong and heartbeat key words for http(s) request and could not find a protocol which it periodically check the status of request.
1) In this you can find an argument for curl command which sets a time interval to send a props(also I monitored this with wireshark). But if still if you unplug the cable neither curl command nor server can understand the connection lost.
curl -k --keepalive-time 5 https://exampel.com/v1/v/f9a64e73/notification
2) Also here explains that there is an http header which is used to use a connection multiple time.
In server side and with nginx web-server we can enable TCP keep-alive probe with so_keepalive=on as listen input argument. Find more information in this link.

When does a http2 TCP connection close?

I understand that http2 uses one tcp connection to serve multiple requests, for example, if I request index.html which contains a.css and a.js, these three requests will be done in one tcp connection.
What happens if user clicks index2.html? does this request still use the same previous tcp connection? If so, will the browser keep the connection open until user closes the browser? And on the server side, does the server keep many connections open all the time?
When using HTTP/2, browsers typically open only one connection per domain.
In your example, index2.html will be sent on the same TCP connection that was used for index.html, a.css and a.js.
In HTTP/2 requests are multiplexed on the same TCP connection, so that the browser can send them concurrently, without waiting for a previous request to be responded to.
Both browsers and servers have an idle timeout for TCP connections.
If the connection is idle for long enough, it will be closed by either party - the one that has the shorter idle timeout, to save resources.
For example, you may open a connection to a wikipedia.org, perform a few requests, and then leave that tab and work on something else.
After a while (typically 30 seconds) the browser will close the TCP connection to wikipedia.org.
On the server side, the server will keep the connections from various clients open, until they are either closed by the client or until the server-side idle timeout fires, at which point it's the server that initiated the close of the TCP connection.
With HTTP/2, the number of connections that a server has to maintain is vastly less than it was with HTTP/1.1.
With HTTP/2, a server has to maintain just 1 TCP connection per client; with HTTP/1.1, the server had to maintain typically 2-8 TCP connections per client.
What happens if user clicks index2.html? does this request still use the same previous tcp connection?
Yes. On top of that, multiple browser tabs/windows also share a single HTTP/2 connection.
If so, will the browser keep the connection open until user closes the browser?
Below from RFC - connection management
For best performance, it is expected that clients will not close
connections until it is determined that no further communication with
a server is necessary (for example, when a user navigates away from a
particular web page) or until the server closes the connection.
Clients SHOULD NOT open more than one HTTP/2 connection to a given
host and port pair.
And on the server side, does the server keep many connections open all the time?
Servers are encouraged to maintain open connections for as long as
possible but are permitted to terminate idle connections if necessary.
When either endpoint chooses to close the transport-layer TCP
connection, the terminating endpoint SHOULD first send a GOAWAY
(Section 6.8) frame so that both endpoints can reliably determine
whether previously sent frames have been processed and gracefully
complete or terminate any necessary remaining tasks.
More info on connection error below.
RFC connection-error-handling
A connection error is any error that prevents further processing of
the frame layer or corrupts any connection state. An endpoint that
encounters a connection error SHOULD first send a GOAWAY frame with
the stream identifier of the last stream that it successfully received
from its peer. The GOAWAY frame includes an error code that indicates
why the connection is terminating. After sending the GOAWAY frame for
an error condition, the endpoint MUST close the TCP connection. It is
possible that the GOAWAY will not be reliably received by the
receiving endpoint. In the event of a connection error, GOAWAY only
provides a best-effort attempt to communicate with the peer about why
the connection is being terminated.
An endpoint can end a connection at any time. In particular, an
endpoint MAY choose to treat a stream error as a connection error.
Endpoints SHOULD send a GOAWAY frame when ending a connection,
providing that circumstances permit it.

HTTP REDIRECT(3xx) TO A DIFFERENT HOST

I'm building a HTTP client(for embedded devices) and I was wondering,
If I receive a HTTP 3xx response, and in the location header I get a hostname different from the one I had in the request. Should I disconnect the TCP connection and reconnect to the new host, or I just need to send a new request with a new host header and keep the old TCP connection alive.
Thank you
It doesn't make sense to reuse the original TCP connection if you're being redirected elsewhere. If my webserver only hosts example.com and I redirect you to elsewhere.net, my webserver will probably not respond to a request for elsewhere.net.
Worse, this also potentially sets you up for a great man-in-the-middle attack if my server redirects you to http://bank.com and you reuse the same TCP connection when sending a request to bank.com. My server can maliciously respond to requests with Host: bank.com, which isn't something you want to happen.
You can't assume the original connection can be reused unless the redirect is to the same same host with the same protocol.
Persistent HTTP connections are a little tricky with the number of client/server combinations. You can avoid the complexity by just wasting time closing and re-establishing each connection:
If you're implementing a HTTP/1.0 client, Connection: keep-alive isn't something you have to implement. Compliant servers should just close the connection after every request if you don't negotiate that you support persistent connections.
If you're implementing a HTTP/1.1 client and don't want to persist the connection, just send Connection: close with your request and a HTTP/1.1 server should close the connection.

Simulating HTTP/TCP re-transmission timeout

I am working on linux.
I have a HTTP client which requests some data from the HTTP server. The HTTP client is written in C and HTTP server is written in perl.
I want to simulate TCP re-transmission timeouts at the client end.
I assume that closing the socket gracefully would not result in client to re-transmit the requests.
So I tried the following scenario:
Exit the Server as soon as it gets the HTTP GET request. However, I noticed that once the application exits, the socket is still closed gracefully. I see that the server initiates FIN.ACK messages towards the client even though the application has not called "close" on the socket. I have noticed this behaviour on a simple TCP server and client written in C program as well.
Server does not send any response to the client's GET request. In this case I notice that there is still FIN, ACK sent by the server.
Seems that in these cases the OS (linux) takes care of closing the socket with the peer.
Is there any way to suppress this behaviour (using ioctl or setsockopt options) or any other way to simulate the TCP re-transmission timeouts.
You could try setting firewall rules that block the packets going from the server to the client, which would cause the client to re-transmit the quests. On Linux, this would probably be done using iptables, but different distributions have different methods of controlling it.
This issue was previously discussed here

Resources