Hi folks. I am trying to get a UDP send-only demo up and running. I started with the project at http://dev.ti.com/tirex/explore/node?node=ADB7cEDeelFwfWnYrD6CnQ__J4.hfJy__LATEST and have modified udpEcho.c so that it looks like:
/*
* Copyright (c) 2015-2018, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* ======== udpEcho.c ========
* Contains BSD sockets code.
*/
#include <pthread.h>
/* BSD support */
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <fcntl.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <ti/net/slnetutils.h>
#include <ti/display/Display.h>
/* Driver Header files */
#include <ti/drivers/GPIO.h>
/* Example/Board Header files */
#include "Board.h"
#define UDPPACKETSIZE 1472
extern Display_Handle display;
extern void fdOpenSession();
extern void fdCloseSession();
extern void *TaskSelf();
/*
* ======== echoFxn ========
* Echoes UDP messages.
*
*/
void *echoFxn(void *arg0)
{
int bytesSent;
int bytesRcvd;
int status;
int sockfd;
struct sockaddr_in localAddr;
struct sockaddr_in clientAddr;
socklen_t addrlen;
char buffer[UDPPACKETSIZE];
uint16_t portNumber = *(uint16_t *)arg0;
char mybuffer[256];
fdOpenSession(TaskSelf());
Display_printf(display, 0, 0, "UDP send demo started\n");
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
Display_printf(display, 0, 0, "Error: socket not created.\n");
goto shutdown;
}
memset(&localAddr, 0, sizeof(localAddr));
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(portNumber);
status = bind(sockfd, (struct sockaddr *)&localAddr, sizeof(localAddr));
if (status == -1) {
Display_printf(display, 0, 0, "Error: bind failed.\n");
goto shutdown;
}
// if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL)|O_NONBLOCK) < 0) {
// Display_printf(display, 0, 0, "Error: fcntl failed.\n");
// }
// char broadcast = '1';
// if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0) {
// Display_printf(display, 0, 0, "Error: setsockopt failed.\n");
// }
// bytesRcvd = recvfrom(sockfd, buffer, UDPPACKETSIZE, MSG_DONTWAIT, (struct sockaddr *)&clientAddr, &addrlen);
// sprintf(mybuffer, "recvfrom returned (%d)", bytesRcvd);
// Display_printf(display, 0, 0, mybuffer);
recvfrom(sockfd, buffer, UDPPACKETSIZE, 0, (struct sockaddr *)&clientAddr, &addrlen);
char* test_buffer = "This is a test!";
Display_printf(display, 0, 0, "Going into loop.\n");
while (1) {
addrlen = sizeof(clientAddr);
bytesSent = sendto(sockfd, test_buffer, strlen(test_buffer), 0, (struct sockaddr *)&clientAddr, addrlen);
if (bytesSent < 0 || bytesSent != strlen(test_buffer)) {
sprintf(mybuffer, "Error: sendto failed (%d)", bytesSent);
Display_printf(display, 0, 0, mybuffer);
// goto shutdown;
}
else {
sprintf(mybuffer, "Send was successful.");
Display_printf(display, 0, 0, mybuffer);
}
}
shutdown:
if (sockfd != -1) {
close(sockfd);
}
fdCloseSession(TaskSelf());
return (NULL);
}
This code runs succesfully as expected, but if I remove the call to recvfrom(), then every call to sendto() in the loop fails. So my questions are:
Why is sendto() dependent on recvfrom() running first?
How can I run sendto() without calling recvfrom()? Is there something that needs to be configured in the NDK stack?
I have also tried setting recvfrom() to be nonblocking, but have not been successful with that.
