Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
20 years ago

LWIP 0.7.1 udp server

Hello @ all!

I want to implement a simple UDP server with the NIOS2 and LWIP 0.7.1.

But there are many problems coding that simple thing. I used some predefined code (found in other newsgroup):

char   smdrBuff;               //Buffer containing ASCII string to send via UDP.
  char*  ptr8;
  char*  buffPtr;                     //Ptr to allocated buffer. 
  struct ip_addr   udpDestIpAddr;     //IP addr to send UDP pkt to.
  struct pbuf*     pbuf1;             //pbuf ptr.
  struct udp_pcb*  udpSkt;            //UDP socket.
  int i = 1;
  
  sprintf(smdrBuff,"This is a test string!!\r\n");  //Msg to send via UDP.
  //S E N D   U D P   M S G.
  buffPtr = mem_malloc(100);                    //Allocate buff for UDP pkt.
  memcpy(buffPtr,smdrBuff,50);
  
  pbuf1 = pbuf_alloc(PBUF_RAW,100,PBUF_RAM);    //Get a pbuf struct.
  pbuf1->payload = (void*) buffPtr;              //Set ptr to UDP msg.
  udpSkt = udp_new();                  //Get a UDP socket.
  ptr8 = (char*) &udpDestIpAddr;
  *ptr8     = 0xc0;                       //Send UDP pkts to 192.168.1.1 (smv PC).
  *(ptr8+1) = 0xa8;
  *(ptr8+2) = 0x01;
  *(ptr8+3) = 0x01;
  udp_connect(udpSkt,&udpDestIpAddr,1000);       //Set-up socket with dest IP and port.
  
  while (i<10) {
  udp_send(udpSkt,pbuf1);
  printf("UDP send...\n");
  i++;                               //Send the UDP msg.
  }

This example runs but with (imo) crazy behaviour...with a packet sniffer i checked the incomming packages and the result is the NIOS sends 10 times ARP requests and the PC responds with the MAC. But the BUFFER is only send once.

does anyone have a running UDP server ?? My goal is to send an image (from ram) permanently to the remote computer.

5 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    PS:

    i use the MoreThanIP gigabit mac with daughtercard (phy). The speed should be 200-300MBit/s. Thats the reason to operate in RAW mode.

    greetings
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    UDP is connectionLESS. In your case, you&#39;re only setting up your connection once.

    Try placing udp_new(), udp_connect(), udp_send() and udp_remove() inside your loop, and it should behave as you&#39;d like.

    Take a look at the DHCP code for a good idea of how a UDP connection should work, using the "raw" API.

    Cheers,

    - slacker
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Oops.

    I think one socket is enough for sending data. Inside the loop it will set up one socket for every packet, destroy it and set up new for the next packet.

    I think if the socket is bound to a remote port it will be able so send data. There is no need to send ARP requests all the time.

    But I will try it. Maybe it works.

    thx and greetings.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    CReal,

    We&#39;re not talking about sockets, with the "raw" api and, according to the documentation, udp_connect() does not generate any network traffic.

    At a minimum, I suggest that you read the rawapi.txt file, where this function is described.

    Here&#39;s a quick code example, which should work, as well. It sets up an "echo" server on port 8.

    #include "echo_udp.h"# include "lwip/debug.h"# include "lwip/stats.h"# include "lwip/udp.h"
    static void
    echo_udp_recv( void* arg, struct udp_pcb *pcb,
                              struct pbuf *p,
                              struct ip_addr *addr,
                              u16_t port )
    {
      err_t err;
      err = udp_connect( pcb, addr, port );
      if (err != ERR_OK)
      {
        printf( "ERROR:  udp_connect() error:  %d\n", err );
      }
      err = udp_send( pcb, p );
      if (err != ERR_OK)
      {
        printf( "ERROR:  udp_send() error:  %d\n", err );
      }
      pbuf_free( p );
      udp_remove( pcb );
      echo_udp_init();
      return;
    }
    void
    echo_udp_init(void)
    {
      struct udp_pcb *pcb;
      pcb = udp_new();
      udp_bind( pcb, IP_ADDR_ANY, 8 );
      udp_recv( pcb, echo_udp_recv, NULL );
    }

    You would have to declare the echo_udp_init() prototype in echo_udp.h and then call this function from within main(), to get things started. Just take a look at the webserver example, shipped with stand alone LWIP, and you&#39;ll see what I mean.

    - slacker