zoukankan      html  css  js  c++  java
  • LWIP互联网资料汇总

    转载自博客:http://blog.csdn.net/liang890319/article/details/8456794

    本文主要搜集了下互联网上关于LWIP的资料和教程

    欢迎补充


    第一部分:移植

    LWIP在UCOS上移植

    LWIP 在STM32上移植   http://www.docin.com/p-459242028.html

    LWIP移植简介  http://www.doc88.com/p-647607123736.html


    第二部分:课件与应用

    LWIP概述

    LWIP PPT课件

    LWIP WIKI

    LWIP中文手册

    LWIP官方文档

    LWIP源代码在线查看  http://www.es.sdu.edu.cn/project/doc/lwip/ref/files.html

    LWIP所有版本源代码在线查看 CVS

    CSDN上相关博客  

    http://blog.csdn.net/zyboy2000/article/category/1140313

    http://blog.csdn.net/beisika10368/article/category/742910


    WIKI和Email  List

    https://savannah.nongnu.org/projects/lwip/
    http://en.wikipedia.org/wiki/LwIP
    http://lists.nongnu.org/mailman/listinfo/lwip-users


    lwip提供三种API:1)RAW API 2)lwip API 3)BSD API。

    LWIP应用指南   RAW-API使用

    RAW-API函数在线查看

    Netconn API函数在线查看   

    SOCKET API在线查看



    第三部分:内核与实现

    LWIP分析  http://wenku.baidu.com/view/a448821b6bd97f192279e947.html###

    LWIP socket实现

    LWIP协议栈分析

    LWIP设计与实现

    LWIP源码详解

    LWIP协议栈源码详解-老衲五木


    第四部分:简单实例(三种API:1)RAW API 2)lwip API 3)BSD API。)

    编程时可参考LWIP WIKI  和本文第三部分资料

    (以下代码主要讲的使用流程,不保证可直接编译运行)


    1,无OS,RAW-api实现

    详细使用可参考致远电子这篇pdf资料 

     http://wenku.baidu.com/view/250d6fd3240c844769eaee6c.html


    更多RAW-API实例  http://www.ultimaserial.com/classroom2.html

    实例1  http://www.ultimaserial.com/avr_lwip_tcp.html

    实例2

    lwIPInit(pucMACArray, inet_addr("10.0.0.10"), inet_addr("255.255.255.0"), inet_addr("10.0.0.1"), IPADDR_USE_STATIC || IPADRR_USE_DHCP);

    but this uses also the auto_ip after the DHCP times-out.

    void ethernet_init(void){
        struct tcp_pcb *pcb;
        struct ip_addr ipaddr;
        u16_t port;

        pcb = tcp_new();
        IP4_ADDR(&ipaddr,  10, 0, 0, 2);
        port=5001;
        
        tcp_err(pcb, ethernet_error);
        err=tcp_connect(pcb, &ipaddr, port, ethernet_send);
        if (err != ERR_OK)
        {
            while(1);
        }
    }

    err_t ethernet_send(void *arg, struct tcp_pcb *pcb, err_t err){
    unsigned int len;

        usprintf(data,"Meetwaarde: %d", value);

        tcp_sent(pcb, ethernet_received);

        len=strlen(data);
        err=tcp_write(pcb, data, len, 0);
                                                   
        if (err != ERR_OK)
        {
            while(1);
        }
        return ERR_OK;
    }

    err_t ethernet_received(void *arg, struct tcp_pcb *tpcb, u16_t len){
        tempCalc=len;
        err=tcp_close(tpcb);
        newDat=true;
        return ERR_OK;
    }

    void ethernet_error(void *arg, err_t err){
    //    Error just wait here
        value=err;
        while(1);
    }




    2,有OS,netconn-API实现

    1、struct netconn * netconn_new(enum netconn_type type)
    创建一个新连接,返回netconn结构体。参数为连接类型,仅应为这两种格式之一:NETCONN_TCP和NETCONN_UDP。
    2、void netconn_delete(struct netconn * conn)
    断开连接,释放conn结构体。
    3、enum netconn_type netconn_type(struct netconn * conn)
    返回协议类型,与netconn_new()的函数参数一样,仅有NETCONN_TCP和NETCONN_UDP两种。
    4、int netconn_peer(struct netconn * conn, struct ip_addr ** addr, unsigned short * port)
    这个函数获得与远端机连接的IP地址填充在“addr”结构体指针中,和端口号填充在“port”中。在未建立连接时,该函数获取值不可预料。
    5、int netconn_addr(struct netconn * conn, struct ip_addr ** addr, unsigned short * port)
    这个函数获取本地IP地址和端口号,与上面函数相似。
    6、int netconn_bind(struct netconn * conn, struct ip_addr * addr, unsigned short port)
    将“conn”连接与本地IP地址和端口号捆绑起来。若IP地址为NULL,则默认系统自定义的IP地址。
    7、int netconn_connect(struct netconn * conn, struct_ip addr * remote_addr, unsigned short remote_port)
    若为UDP协议,设置远端机IP地址和端口号并建立一个连接;若为TCP协议,建立一个远端主机连接。
    8、int netconn_listen(struct netconn * conn)
    TCP协议专用:将TCP连接设置为监听状态。
    9、struct netconn * netconn_accept(struct netconn * conn)
    TCP协议专用:等待一个从远端主机发出的链接请求,“conn”连接必须处于监听状态,即必须事先调用完netconn_listen()函数。主机发出连接请求并成功响应后,会返回一个新连接netconn结构体。
    10、struct netbuf * netconn_recv(struct netconn * conn)
    等待一个连接上接收到数据,如果连接已经被远端主机断开,返回NULL,否则返回数据包到netbuf结构体中。
    11、int netconn_write(struct netconn * conn, void * data, int len, unsigned int flags)
    TCP协议专用:将“data”指向的数据送入TCP连接的发送队列中并发送。发送数据的长度是“len”字节数,长度不受限制。“flags”只能由两个值:
    #define NETCONN_NOCOPY 0x00
    #define NETCONN_COPY   0x01
    NETCONN_COPY表示“data”数据被复制到内部缓存中,这样“data”中的数据便可以在调用这个函数后被修改,但是由于每次发送都需要复制,效率变低,内存需求增加;NETCONN_NOCOPY表示“data”中数据不被复制到内部而是直接使用,这样“data”中的数据在调用这个函数后也不能被修改,知道这个数据被成功发送出去后才可以被修改。这适用于数据存放在ROM中的情况。
    12、int netconn_send(struct netconn * conn, struct netbuf * buf)
    UDP协议专用:将netbuf结构体中指向的数据通过UDP协议的连接发送出去。netbuf结构体中的数据由IP帧格式的限制而不能太多,不能超过1000字节。数据大小在函数中并不检验,发送过大的包会产生不可预知的后果。
    13、int netconn_close(struct netconn * conn)
    断开连接“conn”。



    简单实例1

    1. First, you have to enable timeouts by setting:  
    2.   
    3. #define LWIP_SO_RCVTIMEO 1  
    4.   
    5. Then you have to set up your netconn similarly to this:  
    6.   
    7. pxTCPListener = netconn_new (NETCONN_TCP);  
    8.   
    9. netconn_bind (pxTCPListener, NULL, 23);  
    10.   
    11. netconn_listen (pxTCPListener);  
    12.   
    13. pxNewConnection = netconn_accept (pxTCPListener); //This blocks until connection is accepted  
    14.   
    15. //This is the important line!  
    16.   
    17. pxNewConnection->recv_timeout = 10; //note This is millseconds - lwip works in ms  
    18.   
    19. //This loops until the connection is closed  
    20.   
    21. while(!ERR_IS_FATAL(pxNewConnection->err)) { //Fatal errors include connections being closed, reset, aborted, etc  
    22.   
    23. //This netconn_recv call will now wait 10ms for any new data, then return  
    24.   
    25. if ((pxRxBuffer = netconn_recv (pxNewConnection)) != NULL) {  
    26.   
    27. //Handle received data  
    28.   
    29. }  
    30.   
    31. //Here, do any transmits you want  
    32.   
    33. //End of while loop from above  



    简单实例2  TCP 客户端

    void vTestClient( void *pvParameters )
    {
    (void) pvParameters; // Satisfy complier
    struct netconn *conn;
    struct netbuf *inBuf;
    char pageData[1024];
    char getText[]="GET / HTTP/1.1 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 1.0.3705) Host: www.YourWebsite.com Connection: Keep-Alive ";
    int length, bindErr, connErr, writeErr;
    u16_t port;
    struct ip_addr remoteIP;


    while(true)
    {
    // Create a new socket... API will always create socket 0??
    conn = netconn_new(NETCONN_TCP);
    // There is only one other possible socket open.
    conn->socket = 1; 
    remoteIP.addr = IP_ADDRESS(--,--,--,--);
    connErr = netconn_connect(conn,&remoteIP,80);
    debug_printf("connErr = %d ",connErr);
    if(conn != NULL && connErr == 0)
    {
    writeErr = netconn_write(conn,&getText,sizeof(getText),NETCONN_NOCOPY);
    inBuf = netbuf_new();
    while((inBuf = netconn_recv(conn)) != NULL)
    {
    do
    {
    netbuf_data(inBuf,&pageData,&length); 
    }
    while(netbuf_next(inBuf)>=0);
    }
    if(inBuf != NULL) netbuf_delete(inBuf);
    }
    if(conn != NULL)
    {
    while(netconn_delete(conn) != ERR_OK)
    {
    vTaskDelay(webSHORT_DELAY);
    }
    }
    debug_printf("Sleep ");
    Sleep(300000);
    }

    实例 3 TCP  UDP

    1. http://www.amobbs.com/thread-5059971-1-1.html  
    2. UDP   
    3. {  
    4.         static struct netconn *conn;  
    5.         static struct netbuf  *UDPNetbuf;  
    6.         static struct ip_addr *addr;  
    7.         static struct ip_addr destip;   
    8.         static unsigned short port;          
    9.         unsigned char Array[50];  
    10.         char *pTemp;  
    11.         int DataLen;  
    12.   
    13.         conn = netconn_new(NETCONN_UDP);       /* 创建UDP连接  */  
    14.   
    15.         netconn_bind(conn, IP_ADDR_ANY, 23);  
    16.   
    17.         while(1)  
    18.         {  
    19.                 UDPNetbuf = netconn_recv(conn);                                //接受数据  
    20.   
    21.                 addr = netbuf_fromaddr(UDPNetbuf);   
    22.                 port = netbuf_fromport(UDPNetbuf);  
    23.                 destip = *addr;  
    24.   
    25.   
    26.             netconn_connect(conn, &destip, port);  
    27.   
    28.                 netbuf_copy(UDPNetbuf, Array, UDPNetbuf->p->tot_len);  
    29.   
    30.                 Array[UDPNetbuf->p->tot_len] = '';  
    31.   
    32.             UDPNetbuf->addr=&destip;  
    33.   
    34.         UDPNetbuf->port=port;  
    35.   
    36.             netconn_send(conn, UDPNetbuf);  
    37.   
    38.         netbuf_delete(UDPNetbuf);  
    39.         }          
    40. }  
    41.   
    42.   
    43.   
    44. 这个是TCP的  
    45. {  
    46.     struct netconn *conn, *newconn = NULL;  
    47.     struct netbuf        *TCPNetbuf;  
    48.       
    49.         UARTprintf("TCP_Test_task ");  
    50.   
    51.     conn = netconn_new(NETCONN_TCP);      /* 创建TCP连接  */  
    52.       
    53.     netconn_bind(conn,NULL,80);           /* 绑定本地地址和监听的端口号 */  
    54.       
    55.     netconn_listen(conn);                 /* 进入监听状态 */  
    56.     while(1)  
    57.     {  
    58.       newconn = netconn_accept(conn);    /*阻塞当前进程到有数据接收 */  
    59.       if(newconn != NULL)  
    60.       {      
    61.             if((TCPNetbuf = netconn_recv(newconn)) != NULL)  
    62.             {  
    63.                   
    64.                 netconn_write(newconn,(void *)http_html_hdr,sizeof(http_html_hdr),NETCONN_NOCOPY);  
    65.                                            /* 发送头部数据  */  
    66.                 netconn_write(newconn,(void *)indexdata,sizeof(indexdata),NETCONN_NOCOPY);  
    67.                                            /* 发送实际的WEB页面 */  
    68.                                   
    69.                 netbuf_delete(TCPNetbuf);  
    70.             }            
    71.             netconn_close(newconn);       /* 关闭连接   */  
    72.               
    73.           while(netconn_delete(newconn) != ERR_OK)  
    74.             OSTimeDlyHMSM(0, 0, 1, 0);  
    75.       }  
    76.     }  
    77. }  




    3,有OS,socket实现


    第一步lwip初始化

    1. #include  "lwip/ip_addr.h"  
    2. #include    "lwip/netif.h"  
    3. #include    "lwip/tcpip.h"  
    4. #include "netif/etharp.h"  
    5. #include "lwip/init.h"  
    6.   
    7. #include "inc/hw_ethernet.h"  
    8. #include "inc/hw_ints.h"  
    9. #include "inc/hw_memmap.h"  
    10. #include "inc/hw_nvic.h"  
    11. #include "inc/hw_types.h"  
    12. #include "driverlib/interrupt.h"  
    13. #include "driverlib/ethernet.h"  
    14. #include "driverlib/gpio.h"  
    15. #include "driverlib/sysctl.h"  
    16. #include "driverlib/debug.h"  
    17.   
    18. unsigned char MACAddress[]={0X00,0x14,0x97,0x0F,0x1D,0xE3};  
    19.   
    20. struct netif lwip_netif;  
    21.   
    22. void my_lwip_init(void)  
    23. {  
    24.    extern err_t stellarisif_init(struct netif *netif);  
    25.    extern struct netif lwip_netif;  
    26.    struct ip_addr ipaddr, netmask, gw;  
    27.      
    28.    SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);    /* 复位并使能以太网控制器*/  
    29.    SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);  
    30.       
    31.    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);  /* 使能以太网控制器的指示灯*/  
    32.    GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3, GPIO_DIR_MODE_HW);  
    33.    GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_2 | GPIO_PIN_3,  
    34.                      GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);  
    35.    //IntMasterEnable();                                          //使能总的中断  
    36.      
    37.    SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);                    //使能以太网控制器  
    38.   
    39.     EthernetMACAddrSet(ETH_BASE, (unsigned char *)&MACAddress[0]);       //编程以太网控制器的MAC地址  
    40.      
    41.    tcpip_init(NULL, NULL);  
    42.      
    43.    IP4_ADDR(&ipaddr, 192,168,41,163);  
    44.    IP4_ADDR(&netmask, 255,255,255,0);  
    45.    IP4_ADDR(&gw, 192,168,41,254);  
    46.      
    47.    netif_add(&lwip_netif, &ipaddr, &netmask, &gw, NULL, stellarisif_init, tcpip_input);  
    48.    netif_set_default(&lwip_netif);  
    49.    netif_set_up(&lwip_netif);  
    50.      
    51.    IntPrioritySet(INT_ETH, 0xFF);    /*设置以太网中断优先级*/  
    52.    /* Enable Ethernet TX and RX Packet Interrupts. */  
    53.    EthernetIntEnable(ETH_BASE, ETH_INT_RX | ETH_INT_TX);  
    54.    /* Enable the Ethernet Interrupt handler. */  
    55.    IntEnable(INT_ETH);  
    56. }  


    第二步:调用下面的任务

    1. #include "lwip/opt.h"  
    2. #include "lwip/sys.h"  
    3. #include "lwip/sockets.h"  
    4. #include "string.h"  
    5.   
    6. unsigned char HTTP_GET_STRING[]                      =             
    7.                         "GET";  
    8. #define HTTP_GET_STRING_LEN                                   
    9.                         (sizeof(HTTP_GET_STRING)-1)  
    10. unsigned char htmldata[] = "      
    11. <html>      
    12.     <head>      
    13.         <title>这是个测试文件</title>  
    14.     </head>     
    15.     <body>      
    16.         uCOS-II v2.86 & Lwip v1.3.0 HELLO WORLD!  
    17.     </body>  
    18.     </html>";  
    19.       
    20. void httpd_thread(void *arg)  
    21. {  
    22.     int s, ei, temp;  
    23.   
    24.     struct sockaddr_in serv, cli;  
    25.           
    26.       
    27.     memset(&serv, 0, sizeof(struct sockaddr_in));  
    28.     serv.sin_family = AF_INET;  
    29.     serv.sin_port = htons(80);    
    30.     serv.sin_addr.s_addr = htons(INADDR_ANY);  
    31.       
    32.       
    33.     s = socket(AF_INET, SOCK_STREAM, 0);  
    34.       
    35.     ei = bind(s, (struct sockaddr*)&serv, sizeof(struct sockaddr_in));  
    36.     ei = listen(s, 5);  
    37.       
    38.     while (1)  
    39.     {  
    40.         u32_t len;  
    41.         INT8U cmd[4];  
    42.         temp = accept(s, (struct sockaddr*)&cli, &len);  
    43.         if (temp != -1)  
    44.         {  
    45.             recv(temp, cmd, HTTP_GET_STRING_LEN, 0);  
    46.             cmd[3] = 0;  
    47.               
    48.                   
    49.             send(temp, htmldata, sizeof(htmldata), 0);  
    50.         }  
    51.         close(temp);  
    52.         //OSTimeDlyHMSM(0, 0, 0, 50);  
    53.     }  
    54.  }  





    第五部分其他

    1,常用代码托放网站 

    更详细可参考   http://en.wikipedia.org/wiki/Comparison_of_open_source_software_hosting_facilities

    GitHub(推荐)

    Sourceforge

    Google Code (被q容易打不开)

    Gitorious

    Microsoft's CodePlex

    2,TCP坚持与保活http://blog.sina.com.cn/s/blog_62a85b950101aw8x.html


    http://blog.gkong.com/more.asp?id=154809&Name=john1225cn

    成功实现了LWIP的keepalive功能

    成功实现了LWIP的keepalive功能

    原来的lwip没有启动keepalive功能,导致tcp客户端工作不可靠,主要就是无法处理服务器的断线、断网、down机等异常。表现是服务器故障后,tcp客户端总是等待无法返回,造成锁死。

    处理方法:

    1,使用TCPkeepalive功能,定时探测连接的状态,当发生掉线时,自动关闭连接,正常返回。

    2,检测网线状态PHY寄存器中有标准位。(没有上一种方法好。)

    下面详细介绍如何启动keepalive

    1,打开keepalive的标志使能。

    2,修改keepalive各个计数值,主要是改小,方便测试。

    3,在pcb中需要置位keepalive的一个选项。pcb->so_options |= SOF_KEEPALIVE;

    4,修改pcb的一处bug,该bug可以通过给我汇款获得。

    启动了keepalive才是真正的tcp连接,用起来稳定可靠,异常爽快。


    3

    LwIP中采用netcon接口进行异步读写

    http://wenku.baidu.com/view/e6e44f4b2e3f5727a5e962dc.html

    http://www.rt-thread.org/phpBB3/viewtopic.php?q=phpbbforum/viewtopic.php&f=2&t=277


    4 LWIP netconn函数讲解以及实例

    http://blog.csdn.net/ysdaniel/article/details/6646801


  • 相关阅读:
    Linux安装telnet
    linux 打压缩包
    JAVA读写文件
    LINUX安装NGINX
    Linux安装JDK
    java判断字符串中是否包含中文 过滤中文
    操作MySQL
    Java序列化对象-字符串转换
    nginx
    linux操作命令
  • 原文地址:https://www.cnblogs.com/longbiao831/p/4556276.html
Copyright © 2011-2022 走看看