This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C1294NCPDT: Simple UDP socket programming for the Tiva microcontrollers

Part Number: TM4C1294NCPDT

Dear TI team,

I have a question related to the socket programming of the tiva tm4c1294ncpdt board.

I am trying to run simple code obtained from internet based of socket based UDP programming.

The code is :

/* 
 * udpclient.c - A simple UDP client
 * usage: udpclient <host> <port>
 */
#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 BUFSIZE 1024

/* 
 * error - wrapper for perror
 */
void error(char *msg) {
    perror(msg);
    exit(0);
}

Void tcpHandler(UArg arg0, UArg arg1) {
    int sockfd, portno, n;
    int serverlen;
    struct sockaddr_in serveraddr;
    struct hostent *server;
    char *hostname;
    char buf[BUFSIZE];

    /* check command line arguments */
    if (argc != 3) {
       fprintf(stderr,"usage: %s <hostname> <port>\n", argv[0]);
       exit(0);
    }
    hostname = argv[1];
    portno = atoi(argv[2]);

    /* socket: create the socket */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");

    /* gethostbyname: get the server's DNS entry */
    server = gethostbyname(hostname);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host as %s\n", hostname);
        exit(0);
    }

    /* build the server's Internet address */
    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
	  (char *)&serveraddr.sin_addr.s_addr, server->h_length);
    serveraddr.sin_port = htons(portno);

    /* get a message from the user */
    bzero(buf, BUFSIZE);
    printf("Please enter msg: ");
    fgets(buf, BUFSIZE, stdin);

    /* send the message to the server */
    serverlen = sizeof(serveraddr);
    n = sendto(sockfd, buf, strlen(buf), 0, &serveraddr, serverlen);
    if (n < 0) 
      error("ERROR in sendto");
    
    /* print the server's reply */
    n = recvfrom(sockfd, buf, strlen(buf), 0, &serveraddr, &serverlen);
    if (n < 0) 
      error("ERROR in recvfrom");
    printf("Echo from server: %s", buf);
    return 0;
}

I obtained it from the following site :

https://www.cs.cmu.edu/afs/cs/academic/class/15213-f99/www/class26/udpclient.c

Now when I am going to run this code as it is than I am facing lot of error which is first of all function related to function gethostbyname. which say that it is not defined , so I want to know that how can I access this function in my code as I think since the BSD style network socket is supported in the TI-NDK so I would be able to run this code using the gethostbyname.


Now I did following changes to the code in order to build it successfully:

Void tcpHandler(UArg arg0, UArg arg1)
{
    int sockfd, portno, n;
    int serverlen;
    struct sockaddr_in serveraddr;
    struct hostent *server;
    char *hostname;
    char buf[BUFSIZE];

    /* check command line arguments */
    hostname = "192.168.80.171";
    portno = 8888;

    /* socket: create the socket */
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");

    /* gethostbyname: get the server's DNS entry */
    /*server = gethostbyname(hostname);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host as %s\n", hostname);
        exit(0);
    }*/

    /* build the server's Internet address */
    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    /*bcopy((char *)server->h_addr,
      (char *)&serveraddr.sin_addr.s_addr, server->h_length);*/
    serveraddr.sin_addr.s_addr = inet_addr(hostname);
    serveraddr.sin_port = htons(portno);

    /* get a message from the user */
    bzero(buf, BUFSIZE);
    printf("Please enter msg: ");
    fgets(buf, BUFSIZE, stdin);

    /* send the message to the server */
    serverlen = sizeof(serveraddr);
    n = sendto(sockfd, buf, strlen(buf), 0, &serveraddr, serverlen);
    if (n < 0)
      error("ERROR in sendto");

    /* print the server's reply */
    n = recvfrom(sockfd, buf, strlen(buf), 0, &serveraddr, &serverlen);
    if (n < 0)
      error("ERROR in recvfrom");
    printf("Echo from server: %s", buf);
    return 0;
}

But this code crash showing this:

ss in flash
Starting the TCP Echo example
System provider is set to SysMin. Halt the target to view any SysMin contents in ROV.
Network Added: If-1:192.168.80.154
os.knl.Task: line 383: E_spOutOfBounds: Task 0x20000d08 stack error, SP = 0x3e8.
xdc.runtime.Error.raise: terminating execution

I have used the tcpecho code and removed all the contents in the tcpHandler function and put the content of the code in the main function from the site, as you can see in the code.

So please tell me what is this all about , if anybody wants to emulate the condition than all have to do is replace the content of the tcpHandler with the above code or just copy the above code as it is.

Please tell me why these problems are arising , through my lot of debugging one thing which I come to know is that inspite of BSD socket support by the NDK we can't use the example codes running on linux as it is.

regards

  • Hi,

     If you are going to use the TI-RTOS NDK stack then there is already a udpEcho example that you can reference.

  • At a glance, I assume the stack of the task calling tcpHandler is being blown. You have made this confusing by naming a UDP socket function tcpHandler.

    char buf[1024] will use the entire #define TCPHANDLERSTACK 1024 in the echo example projects. Try increasing this macro.

    To be thorough, you can confirm the problem by clicking Tool -> Runtime Object Viewer -> Task. Then change the Basic option to detailed and you should see a stack peak greater than the stack size. NDK has its own stack(s) which could be blown as well.

  • hi there,

    Now I did experiment with one thing and that is I copied the udpecho code from the TI resource explorer and build it and ran successfully.

    But this is the server code actually and I want to implement the udp client code , so keeping this in mind I did the following changes to the echoFxn() in the udpEcho.c file :

    Void echoFxn(UArg arg0, UArg arg1)
    {
        int                bytesRcvd;
        int                bytesSent;
        int                status;
        int                client;
        fd_set             readSet;
        struct sockaddr_in ServerAddr;
        socklen_t          addrlen;
        char               buffer[UDPPACKETSIZE];
    
        char* hostname = "192.168.80.171";
        int portno = 1000;
    
        client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (client == -1) {
            System_printf("Error: socket not created.\n");
            goto shutdown;
        }
    
        memset(&ServerAddr, 0, sizeof(struct sockaddr_in));
        ServerAddr.sin_family = AF_INET;
        //ServerAddr.sin_addr.s_addr = inet_addr(hostname);
        if(inet_aton(hostname,&ServerAddr.sin_addr) == 0){
            System_abort("Error in adding the Server Ip\n");
        }
        ServerAddr.sin_port = htons(portno);
    
        for(;;){
    
            strcpy(buffer,"Hello Piyush");
    
            addrlen = sizeof(struct sockaddr_in);
            bytesSent = sendto(client, buffer, strlen("Hello Piyush"), 0,
                                    (struct sockaddr *)&ServerAddr, addrlen);
    
            if (bytesSent < 0) {
                System_printf("Error: sendto failed.\n");
                goto shutdown;
            }
    
            //System_printf("Size of two structures:%d\t%d",sizeof(struct sockaddr),sizeof(struct sockaddr_in));
            //System_flush();
    
            /*
             *  readSet and addrlen are value-result arguments, which must be reset
             *  in between each select() and recvfrom() call
             */
    
    #if 1
            FD_ZERO(&readSet);
            FD_SET(client, &readSet);
            addrlen = sizeof(ServerAddr);
    
            /* Wait forever for the reply */
            status = select(client, &readSet, NULL, NULL, NULL);
            if (status > 0) {
                if (FD_ISSET(client, &readSet)) {
                    bytesRcvd = recvfrom(client, buffer, UDPPACKETSIZE, 0,
                            (struct sockaddr *)&ServerAddr, &addrlen);
    
                    if (bytesRcvd > 0) {
    
                    }
                 }
             }
    #endif
    
            Task_sleep(2000);
    
        }
    
    shutdown:
        if (client > 0) {
            close(client);
        }
    }

    The program is build successfully and running , but the problem is that I am able to see the send packet from UDP client to my PC in the wireshark but the receive packet is not seen here and there are list of black messages in the wireshark stating that :

    33844 163.335566   192.168.80.154      192.168.80.171         ICMP             70               Destination unreachable (Port unreachable)

     So I know that I am missing one small thing , but not to locate that point exactly what is that , so I want your help.

    regards

  • What does the code on your PC look like? You need to bind() to the same port your client is connecting to. In general, you shouldn't experiment with ports less than 1024.

  • Hi I am using the port 2050 for the UDP communication.

    Can you please ask TI team to make a copy of  the UDPEcho server code and modify it to a simple UDP Client Code.

    regards 

  • I have tried all the options connect , bind etc but still not able to communicate through the UDP client code .

    Here is the code:

    Void echoFxn(UArg arg0, UArg arg1)
    {
        int                 bytesRcvd;
        int                 bytesSent;
        int                 status;
        int                 client;
        fd_set              readSet;
        struct sockaddr_in  ServerAddr;
        struct sockaddr_in  clientAddr;
        struct timeval      timeout;
        socklen_t           addrlen;
        char                buffer[UDPPACKETSIZE];
    
        char* hostname = "192.168.80.171";
        //int portno = 2050;
    
        memset(&ServerAddr, 0, sizeof(struct sockaddr_in));
        ServerAddr.sin_family = AF_INET;
        ServerAddr.sin_addr.s_addr = inet_addr(hostname);
        /*if(inet_aton(hostname,&ServerAddr.sin_addr) == 0){
            System_abort("Error in adding the Server Ip\n");
        }*/
        //ServerAddr.sin_port = htons(portno);
        ServerAddr.sin_port = htons(arg0);
    
        for(;;){
    
            client = socket(ServerAddr.sin_family, SOCK_DGRAM, IPPROTO_UDP);
            if (client == -1) {
                System_printf("Error: socket not created.\n");
                goto shutdown;
            }
    
            status = 0;
            status = connect(client,(struct sockaddr *)&ServerAddr,sizeof(struct sockaddr));
            if(status == -1)
            {
                System_printf("Error: Connect failed.\n");
                goto shutdown;
            }
    
            timeout.tv_sec = 10;
            timeout.tv_usec = 0;
    
            status = setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));
            if(status < 0){
                System_printf("Error: timeout failed.\n");
                goto shutdown;
            }
    
            strcpy(buffer,"Hello Piyush");
    
            addrlen = sizeof(struct sockaddr);
            bytesSent = send(client, buffer, strlen("Hello Piyush"), 0);
    
            if (bytesSent < 0) {
                System_printf("Error: sendto failed.\n");
                goto shutdown;
            }
    
            FD_ZERO(&readSet);
            FD_SET(client, &readSet);
            addrlen = sizeof(ServerAddr);
    
            /* Wait forever for the reply */
            status = select(client, &readSet, NULL, NULL, &timeout);
            if (status > 0) {
                if (FD_ISSET(client, &readSet)) {
                    bytesRcvd = recv(client, buffer, UDPPACKETSIZE, 0);
    
                    if (bytesRcvd < 0) {
                        System_printf("Error: recvfrom failed.\n");
                        goto shutdown;
                    }
                 }
             }
    
            close(client);
    
            //Task_sleep(2000);
        }
    
    shutdown:
        if (client > 0) {
            close(client);
        }
    }

    Please if possible make a simple UDP client at your end and post the zipped file here.

    regards

  • Hi Piyush,

    You can try using the updSendReceive "example" as a base, it should have what you need. It can be found at:
    <tirtos install dir>/packages/examples/tools/udpSendReceive.c

    Hope that helps,
    Gerardo

  • I have already checked that , see I have gone through almost all the posts in this forum related to my problem and have tried all of them although they were partial solutions or infact with no solutions , but all effort is not fruitful yet.

    The source which you are talking is actually PC application which will compile on linux PC and will run on it.

    regards

  • Hi Piyush,

    Since that uses bsd sockets the code could be modified slightly to be able to run on NDK.

    You say it's not working but you don't go into much detail, are some of your calls returning an error? 

    BR,
    Gerardo

  • Hi Piyush,

    Did this get resolved? Can I mark it as "TI Thinks Resolved"?

    Todd

    [Updates: I'm marking this a TI Thinks Resolved and closing it because of inactivity from the original poster. If you feel otherwise, please post a response and the thread will be opened.]