How to send a simple HTTP request using the lwIP stack?

Please move / close this if the question doesn't matter.

Kernel: Cortex-M4

Microprocessor: TI TM4C1294NCPDT.

IP Stack: lwIP 1.4.1

I use this microprocessor to perform some data logging, and I want to send some information to a separate web server via an HTTP request in the form:

http://123.456.789.012:8800/process.php?data1=foo&data2=bar&time=1234568789

and I want the processor to see the response header (i.e. if it was 200 OK or something went wrong) - it does not need to display / receive the actual content.

lwIP has an http server for the microprocessor, but I'm after another (microprocessor is the client).

I am not sure how packets relate to request / response headers, so I'm not sure how I should send / receive information.

+6
source share
2 answers

It turned out to be quite simple to implement, I forgot to update this question.

I pretty much followed the instructions on this site, which is the Raw / TCP documentation.

Basically, the HTTP request is encoded in TCP packets, so to send data to my PHP server, I sent an HTTP request using TCP packets (lwIP does all the work).

The HTTP packet I want to send looks like this:

HEAD / process.php? Data1 = 12 & data2 = 5 HTTP / 1.0

Host: mywebsite.com

To "translate" this into text that the HTTP server understands, you must add the "\ r \ n" carriage return / new line to your code. So it looks like this:

 char *string = "HEAD /process.php?data1=12&data2=5 HTTP/1.0\r\nHost: mywebsite.com\r\n\r\n "; 

Please note that the end has two lots "\ r \ n"

You can use GET or HEAD, but due to the fact that I didn’t like the HTML site returned by my PHP server, I used HEAD (it returns 200 OK to success or other code if it fails).

lwIP raw / tcp works with callbacks. You basically configure all the callback functions, then click the data you want on the TCP buffer (in this case, the above TCP line), and then you specify lwIP to send the packet.

Function for configuring a TCP connection (this function is directly called by my application every time I want to send a TCP packet):

 void tcp_setup(void) { uint32_t data = 0xdeadbeef; /* create an ip */ struct ip_addr ip; IP4_ADDR(&ip, 110,777,888,999); //IP of my PHP server /* create the control block */ testpcb = tcp_new(); //testpcb is a global struct tcp_pcb // as defined by lwIP /* dummy data to pass to callbacks*/ tcp_arg(testpcb, &data); /* register callbacks with the pcb */ tcp_err(testpcb, tcpErrorHandler); tcp_recv(testpcb, tcpRecvCallback); tcp_sent(testpcb, tcpSendCallback); /* now connect */ tcp_connect(testpcb, &ip, 80, connectCallback); } 

Once the connection to my PHP server is established, the connectCallback function is called by lwIP:

 /* connection established callback, err is unused and only return 0 */ err_t connectCallback(void *arg, struct tcp_pcb *tpcb, err_t err) { UARTprintf("Connection Established.\n"); UARTprintf("Now sending a packet\n"); tcp_send_packet(); return 0; } 

This function calls the actual tcp_send_packet () function, which sends an HTTP request, as follows:

 uint32_t tcp_send_packet(void) { char *string = "HEAD /process.php?data1=12&data2=5 HTTP/1.0\r\nHost: mywebsite.com\r\n\r\n "; uint32_t len = strlen(string); /* push to buffer */ error = tcp_write(testpcb, string, strlen(string), TCP_WRITE_FLAG_COPY); if (error) { UARTprintf("ERROR: Code: %d (tcp_send_packet :: tcp_write)\n", error); return 1; } /* now send */ error = tcp_output(testpcb); if (error) { UARTprintf("ERROR: Code: %d (tcp_send_packet :: tcp_output)\n", error); return 1; } return 0; } 

Once the TCP packet has been sent (all this is necessary if you want to “hope for the best” and don’t care if the data is actually sent), the PHP server returns the TCP packet (with 200 OK, etc. and HTML code if you used GET instead of HEAD). This code can be read and verified in the following code:

 err_t tcpRecvCallback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { UARTprintf("Data recieved.\n"); if (p == NULL) { UARTprintf("The remote host closed the connection.\n"); UARTprintf("Now I'm closing the connection.\n"); tcp_close_con(); return ERR_ABRT; } else { UARTprintf("Number of pbufs %d\n", pbuf_clen(p)); UARTprintf("Contents of pbuf %s\n", (char *)p->payload); } return 0; } 

p-> The payload contains the actual information "200 OK", etc. Hope this helps someone.

I missed some errors in my code above to simplify the answer.

+12
source

Take a look at the HTTP example on Wikipedia. The client will send the GET and HOST lines. For the response to the server, many lines will respond. The first line will have a response code.

0
source

Source: https://habr.com/ru/post/976251/


All Articles