  | 
      
        
          1楼
          巨大八爪鱼
          2017-3-18 17:09
          
          
           
         
        err_t http_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {     const char *str = "HTTP/1.1 200 OK\r\nDate: Sat, 13 Feb 2016 12:02:41 GMT\r\nServer: Apache/2.4.7 (Ubuntu)\r\nX-Powered-By: PHP/5.5.9-1ubuntu4.14\r\nContent-Length: 19\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n<b>Hello World!</b>";     if (p != NULL)     {         tcp_write(tpcb, str, strlen(str), 0);         pbuf_free(p);     }     return ERR_OK; }
  err_t http_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {     tcp_recv(newpcb, http_recv);     return ERR_OK; }
  void init_http(void) {     struct tcp_pcb *tpcb = tcp_new();     tcp_bind(tpcb, IP_ADDR_ANY, 80);     tpcb = tcp_listen(tpcb);     tcp_accept(tpcb, http_accept); } 
       | 
    
    
        | 
      
        
          2楼
          巨大八爪鱼
          2017-3-18 17:11
          
          
           
         
        const char *str = "HTTP/1.1 200 OK\r\nContent-Length: 19\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n<b>Hello World!</b>"; 可以将响应字符串中的Date和Server信息去掉。
  
       | 
    
    
        | 
      
        
          3楼
          巨大八爪鱼
          2017-3-18 17:22
          
          
           
         
        【变量i自加测试】 err_t http_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {     static uint8_t i = 0;     char str[200];     sprintf(str, "HTTP/1.1 200 OK\r\nContent-Length: 12\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n<b>i</b>=%-3d", i);     i++;          if (p != NULL)     {         tcp_write(tpcb, str, strlen(str), TCP_WRITE_FLAG_COPY); // str是局部变量, 函数退出时会被撤销, 所以需要复制内存         pbuf_free(p);     }     return ERR_OK; }
  
       | 
    
    
        | 
      
        
          4楼
          巨大八爪鱼
          2017-3-18 17:26
          
          
           
         
        收到的HTTP响应:   
       | 
    
    
        | 
      
        
          5楼
          巨大八爪鱼
          2017-3-18 17:35
          
          
           
         
        【在网页上原封不动地显示浏览器请求内容】 err_t http_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {     char str[800];     uint16_t len;     if (p != NULL)     {         sprintf(str, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n", p->len);         len = strlen(str);         strncpy(str + len, p->payload, p->len);         tcp_write(tpcb, str, len + p->len, TCP_WRITE_FLAG_COPY);         pbuf_free(p);     }     return ERR_OK; }
  
       | 
    
    
        | 
      
        
          6楼
          巨大八爪鱼
          2017-3-18 17:49
          
          
           
         
        【在网页上原封不动地显示浏览器请求内容,且自动把\n换成<br>,方便查看】 err_t http_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {     char ch;     char str[800];     uint16_t i, j, len;     if (p != NULL)     {         // 先统计一下HTML内容有多少         len = 0;         for (i = 0; i < p->len; i++) // 扫描整个请求字符串         {             ch = *((char *)p->payload + i);             if (ch == '\n')                 len += 4;             else if (ch != '\r') // 忽略\r字符                 len++;         }                  sprintf(str, "HTTP/1.1 200 OK\r\nContent-Length: %d\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n", len);         len = strlen(str); // 请求头的长度         j = len;         for (i = 0; i < p->len; i++)         {             ch = *((char *)p->payload + i);             if (ch == '\n')             {                 // 换行符                 str[j++] = '<';                 str[j++] = 'b';                 str[j++] = 'r';                 str[j++] = '>';             }             else if (ch != '\r')                 str[j++] = ch; // 其他字符         }         tcp_write(tpcb, str, j, TCP_WRITE_FLAG_COPY);         pbuf_free(p);     }     return ERR_OK; }
  
       | 
    
    
        | 
      
        
          7楼
          巨大八爪鱼
          2017-3-18 17:52
          
          
           
         
        自动换行的效果:
    
       | 
    
    
        | 
      
        
          8楼
          巨大八爪鱼
          2017-3-18 17:53
          
          
           
         
        【测试用的Java程序:用于查看返回的响应内容】 import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException;
  public class Demo {     public static void main(String[] args) {         try {             Socket sock = new Socket("192.168.0.2", 80);             byte[] b = new byte[1024];                          PrintWriter pw = new PrintWriter(sock.getOutputStream());             pw.write("ha\r\nha");             pw.flush();                          sock.getInputStream().read(b);             System.out.println(new String(b));             sock.close();         } catch (UnknownHostException e) {             e.printStackTrace();         } catch (IOException e) {             e.printStackTrace();         }     } }
  
       | 
    
    
        | 
      
        
          9楼
          巨大八爪鱼
          2017-3-19 17:11
          
          
           
         
        【智能化程序:自动计算HTML内容的长度】 #include <string.h> #include "lwip/tcp.h" // 一般情况下需要包含的头文件
  #define STR_AND_SIZE(str) (str), strlen(str)
  err_t http_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {     char len[10]; // 存放HTML内容的长度     char str[50]; // 存放HTML内容          const char *colors[] = {"red", "blue", "green"};     static int32_t i = 1;     static uint8_t color_i = 0;          if (p != NULL)     {         tcp_recved(tpcb, p->tot_len);                  // 动态生成HTML内容         sprintf(str, "<div><b style=\"color:%s\">i</b>=%d</div>", colors[color_i], i);         if (i == -1)             i = -2;         i = i * 2 + 1;         color_i++;         if (color_i == sizeof(colors) / sizeof(char *))             color_i = 0;                  sprintf(len, "%d", strlen(str)); // 计算出HTML内容的长度并转换为字符串         tcp_write(tpcb, STR_AND_SIZE("HTTP/1.1 200 OK\r\nContent-Length: "), TCP_WRITE_FLAG_MORE);         tcp_write(tpcb, STR_AND_SIZE(len), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);         tcp_write(tpcb, STR_AND_SIZE("\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n"), TCP_WRITE_FLAG_MORE);         tcp_write(tpcb, STR_AND_SIZE(str), TCP_WRITE_FLAG_COPY); // 发送HTML内容         pbuf_free(p);     }     return ERR_OK; }
  err_t http_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {     tcp_recv(newpcb, http_recv);     return ERR_OK; }
  void init_http(void) {     struct tcp_pcb *tpcb = tcp_new();     tcp_bind(tpcb, IP_ADDR_ANY, 80);     tpcb = tcp_listen(tpcb);     tcp_accept(tpcb, http_accept); }
  
       | 
    
    
        | 
      
        
          10楼
          巨大八爪鱼
          2017-3-19 17:22
          
          
           
         
        
          
          【在网页上原封不动地显示浏览器请求内容,且自动把\n换成<br>,方便查看】 err_t http_recv(void *arg, struct tcp_pcb *tpcb, str...
  
         
        【改进后的程序】 err_t http_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {     char len[10]; // 存放HTML内容的长度     char str[500]; // 存放HTML内容     char ch;     uint16_t i;     uint16_t j = 0;     if (p != NULL)     {         for (i = 0; i < p->len; i++)         {             ch = *((char *)p->payload + i);             if (ch == '\n')             {                 // 换行符                 str[j++] = '<';                 str[j++] = 'b';                 str[j++] = 'r';                 str[j++] = '>';             }             else if (ch != '\r')                 str[j++] = ch; // 其他字符         }         tcp_recved(tpcb, p->tot_len);         sprintf(len, "%d", j); // j就是生成的HTML内容的长度                  tcp_write(tpcb, STR_AND_SIZE("HTTP/1.1 200 OK\r\nContent-Length: "), TCP_WRITE_FLAG_MORE);         tcp_write(tpcb, STR_AND_SIZE(len), TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE);         tcp_write(tpcb, STR_AND_SIZE("\r\nKeep-Alive: timeout=5, max=100\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n"), TCP_WRITE_FLAG_MORE);         tcp_write(tpcb, str, j, TCP_WRITE_FLAG_COPY); // 发送HTML内容         pbuf_free(p);     }     return ERR_OK; } 
       |