Forum Discussion

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

Simple Socket Client

Hey,

I need programming a client Ethernet interface to send data from my Nios (EP2S60 device+LAN91C111) to a PC, and i only found server examples which makes my start more difficult.

Does anyone have an example of client interface for TCP or UDP?

Thanks in advance.

5 Replies

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

    Hi Redbeard,

    Funny, I have a similar requirement. First, take a look at this sockets tutorial.... http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html (http://www.cs.rpi.edu/courses/sysprog/sockets/sock.html)

    The simplest approach is to implement a socket client on NIOS. So here's a trivial socket client (modelled on the tutorial). BTW, this code runs nicely on NIOS (under uClinux, with network support and LAN91C111 driver enabled).....

    // tty2sock.cpp
    // ============# include <stdio.h># include <stdlib.h># include <string.h># include <unistd.h># include <sys/types.h># include <sys/socket.h># include <netinet/in.h># include <netdb.h> 
    # define SERVER_NAME    "192.168.0.78"           // Your server IP goes here# define SERVER_PORT    4000
    void error(char *msg)
    {
       perror(msg);
       exit(0);
    }
    int main(int argc, char *argv)
    {
      struct sockaddr_in serv_addr;
      char buffer    = { 0 };
      printf  ("Hello from tty2sock!\n");
      FILE*    ttyPort  = fopen    ("/dev/tty", "r");
      int portNumber    = SERVER_PORT;
      printf  ("portNumber=0x%8x\n", portNumber);
      int sockHandle    = socket(AF_INET, SOCK_STREAM, 0);
      printf  ("sockHandle=0x%8x\n", sockHandle);
      if (sockHandle < 0)
      { 
        error  ("ERROR opening socket");
      }
      struct hostent* server = gethostbyname(SERVER_NAME);
      if (server == NULL)
      {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
      }
      
      memset    (&serv_addr, 0, sizeof(serv_addr));
      serv_addr.sin_family    = AF_INET;
      bcopy  ((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
      serv_addr.sin_port    = htons(SERVER_PORT);
      if (connect(sockHandle,(const sockaddr*)&serv_addr,sizeof(serv_addr)) < 0)
      { 
        error  ("ERROR connecting");
      }
      printf  ("Enter a message: ");
      bzero      (buffer, 256);
      fgets      (buffer, 255, stdin);
      printf  ("buffer=\n", buffer);
      int n      = write(sockHandle,buffer,strlen(buffer));
      if (n < 0)
      { 
        error  ("ERROR writing to socket");
      }
      return  0;
    }

    Next, here&#39;s the corresponding socket server (also modelled on the tutorial). BTW, this server is running on a Debian Linux box...

    // socketServer.cpp
    // ================
    // A simple server in the internet domain using TCP
    // The port number is passed as an argument # include <stdio.h># include <stdlib.h># include <string.h># include <netinet/in.h># include <sys/types.h> # include <sys/socket.h># include <unistd.h>
    void error(char *msg)
    {
      perror    (msg);
      exit  (1);
    }
    int main    (int argc, char *argv)
    {
      int sockfd, newsockfd, portno;
      socklen_t clilen    = 0;
      char buffer;
      struct sockaddr_in serv_addr, cli_addr;
      int n;
      
      if (argc < 2)
      {
        fprintf(stderr,"ERROR, no port provided\n");
        exit(1);
      }
      
      sockfd = socket(AF_INET, SOCK_STREAM, 0);
      
      if (sockfd < 0)
      { 
        error("ERROR opening socket");
      }
      
    //bzero((char *) &serv_addr, sizeof(serv_addr));
      memset    (&serv_addr,
          0,
          sizeof(serv_addr));
      portno = atoi(argv);
      serv_addr.sin_family = AF_INET;
      serv_addr.sin_addr.s_addr = INADDR_ANY;
      serv_addr.sin_port = htons(portno);
      if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
      {
        error("ERROR on binding");
      }
      
      listen(sockfd,5);
      clilen = sizeof(cli_addr);
      newsockfd = accept(sockfd, 
          (struct sockaddr *)&cli_addr, 
           (socklen_t*)&clilen);
      if (newsockfd < 0)
      {
        error("ERROR on accept");
      }
      
      bzero(buffer,256);
      n = read(newsockfd,buffer,255);
      if (n < 0)
      {
        error("ERROR reading from socket");
      }
      
      printf("Here is the message: %s\n",buffer);
      return 0; 
    }

    How to run it...

    1) Compile the socketServer app on your PC. I&#39;m using Eclipse on Debian.

    2) Cross-compile and link the tty2sock app as follows....

    nios2-linux-uclibc-c++ tty2sock.cpp -o tty2sock -elf2flt="-s 64000"
    cp tty2sock ~/rootfs/bin

    3) Startup the server on PC, supplying PORT on the command-line...eg. "socketServer 4000"

    4) Execute tty2sock on NIOS

    nios-terminal -->

    tty2sock -->

    "The quick brown fox jumps over the lazy dog"

    5) Your message should gurgle out on the server.

    Hope this helps
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi @ all,

    for anyone who is interested: I made a udp-server/client with lwip. It&#39;s a stand-alone server for EP2S60.

    Unfortunately I seem to have lost my udp-server example. But it was based on the stand-alone web server example from the lwip-stack.

    Cheers,

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

    Here is my code based on the Web server LWIp example :

    I have files user.h, network_utilities.h, web_server.c (converted in eth_client.c) and my below file send.c :

    #include <stdio.h># include <stdlib.h># include <string.h># include <ctype.h># include <sys/param.h># include <sys/fcntl.h># include "lwip/netif.h"# include "lwip/sockets.h"# include "arch/sys_arch.h"# include "sys/alt_alarm.h"# include "alt_types.h"# include "user.h"# include "io.h"
    # ifdef DEBUG
     # include alt_debug.h# else
     # define ALT_DEBUG_ASSERT(a) # endif /* DEBUG */
    # define   nbc                   100 // 225 // 200# define   nbl                   200 // 200 // 250# define   fps                   75
    # define   SEND_PORT             30    // TCP port number to listen on 
    int handle_send(int sock)
    {
      char* buffer;
      int i, j;
      int n, a, k;
      buffer=(char *)calloc(nbl*nbc, sizeof(char));
      
      for (i=0; i<nbl; i++) //Ecriture sur nbl lignes
      { 
        for(j=0; j<nbc; j++) // une ligne contient nbc pixels
        {  
           buffer = (char)(j+1);
        }
      }   
      printf(" Buffering data finished\n");
      printf(" Buffer length : %d\n", strlen(buffer));
     
      n = send(sock, buffer, strlen(buffer),0);
      //int lwip_send(int s, void *dataptr, int size, unsigned int flags);
      if (n < 0)
        die_with_error(" error writing to socket\n");
      return n;
    }
    void send_task()
    {
      int sock;
      struct  sockaddr_in addr;
      
      printf(" Creating socket\n");
      if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        die_with_error(" Listening socket creation failed");
      
      addr.sin_family = AF_INET;
      addr.sin_port = htons(SEND_PORT);
      addr.sin_addr.s_addr = inet_addr("10.0.0.11");
     
      while ((connect(sock,(struct sockaddr *)&addr,sizeof(addr))) < 0)
        printf(" Trying to connect to server\n");
      printf(" Client sending on port %d\n", SEND_PORT);
      
      if ((handle_send(sock)) <0)
          printf(" Transmit failed\n");
      printf(" End of Connection\n");
      close(sock);
    }

    With that code, i can&#39;t send more than a buffer of 100x200 char. And i don&#39;t understand why! My pc server seems to correctly receive the data anyway.

    So are there parameters to change in LWIP to send a certain amount of data like buffers or stacks?

    Thanks for ur future answers.

    Regards,

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

    Hi hootsmon,

    How do you run the code you cross compiled in the Nios processor?

    Sorry for the dumb question. I am a newbie on Nios stuff.

    Thanks,

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

    Hi Lord_Redbeard

    Is your work is based on the DE2_WEB?Can you tell me how to modify the project to connect to the server on PC?

    I made a client in the project, and I could get reply from the DE2 board with commadn "Ping".but it could not connect to the server on PC?Did you have the problem?