2014-10-04 16 views
6

Vui lòng di chuyển/đóng này nếu câu hỏi không liên quan.Làm cách nào để gửi yêu cầu HTTP đơn giản với ngăn xếp lwIP?

Core: Cortex-M4

Bộ vi xử lý: TI TM4C1294NCPDT.

IP Stack: lwIP 1.4.1

Tôi đang sử dụng bộ vi xử lý này để làm một số ghi chép dữ liệu, và tôi muốn gửi một số thông tin đến một máy chủ web riêng biệt thông qua một yêu cầu HTTP trong các hình thức:

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

và tôi muốn bộ xử lý có thể xem tiêu đề phản hồi (tức là nếu nó là 200 OK hoặc đã xảy ra sự cố) - nó không phải hiển thị/nhận nội dung thực tế.

lwIP có máy chủ http cho bộ vi xử lý, nhưng tôi là người đối diện (bộ vi xử lý là máy khách).

Tôi không chắc chắn về cách các gói tương quan với các tiêu đề yêu cầu/phản hồi, vì vậy tôi không chắc chắn cách tôi thực sự gửi/nhận thông tin.

Trả lời

12

Điều này đã trở nên khá đơn giản để triển khai, hãy quên cập nhật câu hỏi này.

Tôi thực hiện theo các hướng dẫn trên trang web this, là tài liệu Nguyên/TCP '. Về cơ bản, yêu cầu HTTP được mã hóa trong các gói TCP, vì vậy để gửi dữ liệu đến máy chủ PHP của tôi, tôi đã gửi một yêu cầu HTTP bằng cách sử dụng các gói TCP (lwIP thực hiện tất cả công việc).

Các gói HTTP Tôi muốn gửi trông như sau:

ĐẦU /process.php?data1=12 & data2 = 5 HTTP/1.0

Host: mywebsite.com

Để "dịch" văn bản này được hiểu bởi máy chủ HTTP, bạn phải thêm "\ r \ n" dấu xuống dòng/dòng mới trong mã của mình. Vì vậy, nó trông như thế này:

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

Lưu ý rằng cuối cùng có hai rất nhiều "\ r \ n"

Bạn có thể sử dụng GET hoặc HEAD, nhưng vì tôi không quan tâm đến trang web HTML PHP của tôi máy chủ trả về, tôi đã sử dụng HEAD (nó trả về 200 OK khi thành công hoặc mã khác về lỗi).

Nguyên tắc lwIP/tcp hoạt động trên các cuộc gọi lại. Bạn về cơ bản thiết lập tất cả các chức năng gọi lại, sau đó đẩy dữ liệu bạn muốn vào bộ đệm TCP (trong trường hợp này, chuỗi TCP được chỉ định ở trên), và sau đó bạn yêu cầu lwIP gửi gói.

Chức năng để thiết lập một kết nối TCP (chức năng này là trực tiếp gọi bằng ứng dụng của tôi mỗi khi tôi muốn gửi một gói tin TCP):

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); 

} 

Khi một kết nối đến máy chủ PHP của tôi được thiết lập, ' chức năng connectCallback' được gọi bởi 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; 
} 

chức năng này gọi hàm tcp_send_packet thực tế() mà gửi yêu cầu HTTP, như sau:

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; 
} 

Khi gói TCP đã được gửi (tất cả điều này là cần thiết nếu bạn muốn "hy vọng điều tốt nhất" và không quan tâm nếu dữ liệu thực sự được gửi), máy chủ PHP trả về gói TCP (với 200 OK , vv và mã HTML nếu bạn sử dụng GET thay vì HEAD). Mã này có thể được đọc và xác minh trong mã sau:

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-> tải trọng chứa thông tin "200 OK" thực tế, v.v. Hy vọng rằng điều này sẽ giúp một ai đó.

Tôi đã bỏ sót một số lỗi khi kiểm tra mã của tôi ở trên để đơn giản hóa câu trả lời.

0

Hãy xem qua số HTTP example trong Wikipedia. Khách hàng sẽ gửi các dòng GET và HOST. Máy chủ sẽ phản hồi với nhiều dòng cho một phản hồi. Dòng đầu tiên sẽ có mã phản hồi.

+0

Vâng, tôi đã xem xét nhiều lần. Tôi đã có một câu trả lời cụ thể hơn về việc thực hiện nó thông qua thư viện lwIP. Tôi nghĩ rằng tôi đã gần như figured nó ra thông qua api thô/tcp - sẽ kiểm tra nó ra sớm. – tgun926

Các vấn đề liên quan