Other Parts Discussed in Thread: SYSBIOS
Tool/software: Code Composer Studio
What is the equivalent of ioctl function to setup socket io to be nonblocking
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.
Tool/software: Code Composer Studio
What is the equivalent of ioctl function to setup socket io to be nonblocking
Hi,
I'm not clear with your question. If you are referring to socket io as described in the wikipedia https://en.wikipedia.org/wiki/Socket.IO then we don't have any library and support for this. If this is not your question, please clarify.
Hi Charles:
here is what I am trying to do :
rc = ioctl(server, FIONBIO, (char *)&on);
To setup calls of socket file to be unblocking.
Using examples which TI rtos provided , recv call was able to detect that I removed Ethernet cable .
it looks like recv is blocking call and I need to make it unlooking to detect loss of Ethernet connection
Hi Sergey,
Thanks for the clarification, I will forward your question to our TI-RTOS NDK expert.
Hi Sergey,
The equivalent function and option within the NDK is the `NDK_setsockopt` function with the `SO_BLOCKING` flag.
Best,
Brandon
Hi Brandon , by any chance to you have code example to to use this NDK_setsockopt.
Thanks
Certainly,
SOCKET server; // socket int status; int val = 0; // optval or pbuf status = NDK_setsockopt(server, SOL_SOCKET, SO_BLOCKING, &val, sizeof(val));
Brandon
Hi Brandon:
I put your code in but got warning:
if ( NDK_setsockopt(server, SOL_SOCKET, SO_BLOCKING, &optval, sizeof(optval))<0 )
"../aim_firmware.c", line 705: warning #169-D: argument of type "int" is incompatible with parameter of type "SOCKET"
Socket type is void * not int.
What I am doing wrong ?
Hi Sergey,
I assumed you were using the NDK directly, but that may have been a mistake on my part. Can I see a bit of the rest of your code? I'm guessing you have some sort of socket handle already. I'd specifically like to see what function you called to acquire your socket handle - possibly `NDK_socket` or `socket`. If using the NDK_* functions they will take a SOCKET type, not an int - also my mistake.
Brandon
Hi Brandon:
here is my code taken from your example
int server
server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
status = bind(server, (struct sockaddr *)&localAddr, sizeof(localAddr));
status = listen(server, NUMTCPWORKERS);
clientfd = accept(server, (struct sockaddr *)&clientAddr, &addrlen)) != -1)
while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0)
if bytesRcv == I do disconnet ,
but if I remove Ethernet cable recv do not report this error.
How I can detect cable disconnect in this case ?
My recv reruns me only bytes received or 0 , but not an error.
Thanks a lot.
I spend already 2 days to make it work, but I am still near solution.
Thanks
Hi,
Thanks for providing that.
Okay, you should use the `setsockopt` function. It's provided in the BSD layer along with the other networking functions you've used. Its arguments should be as I suggested earlier. I believe you're working from an example provided in the SDK? If that is the case, the following should work
int server; // socket int status; int val = 0; // optval or pbuf status = setsockopt(server, SOL_SOCKET, SO_NONBLOCKING, &val, sizeof(val));
Let me know how it goes.
Brandon
Hi Brandon:
I was trying to compile sample of you code :
if ( setsockopt(server, SOL_SOCKET, SO_NONBLOCKING, &optval, sizeof(optval))<0 )
error #20: identifier "SO_NONBLOCKING" is undefined
Hi,
SO_BLOCKING may be the correct option then.
What example application did you start from?
Please correct me if I'm wrong: Based on your earlier comments it looks like you're using the tcpecho example. SO_NONBLOCKING should work just fine in that example. It's defined in sys/socket.h which is included by tcpEcho.c.
It's a bit confusing, but I suggested trying SO_BLOCKING because, if using the NDK, that is what the option is called. If using the BSD layer, which the tcpecho examples does, the option is SO_NONBLOCKING.
Brandon
Hi Brandon:
here is example which I used I cut and paste tcpEcho.c file which is in
C:\ti\tirtos_tivac_2_16_00_08\tirtos_tivac_2_16_00_08_examples\TI\DK_TM4C129X\tcpEcho
Plus to my code I added
if ( setsockopt(server, SOL_SOCKET, SO_BLOCKING, &optval, sizeof(optval))<0 )
{
System_printf("Error: setsockopt failed\n");
Shutdown ( server); /// close opened socket.
return;
}
/*
* Copyright (c) 2014-2015, 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.
*/
/*
* ======== tcpEcho.c ========
* Contains BSD sockets code.
*/
#include <string.h>
#include <xdc/std.h>
#include <xdc/runtime/Error.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/drivers/GPIO.h>
/* NDK BSD support */
#include <sys/socket.h>
/* Example/Board Header file */
#include "Board.h"
#define TCPPACKETSIZE 256
#define NUMTCPWORKERS 3
/*
* ======== tcpWorker ========
* Task to handle TCP connection. Can be multiple Tasks running
* this function.
*/
Void tcpWorker(UArg arg0, UArg arg1)
{
int clientfd = (int)arg0;
int bytesRcvd;
int bytesSent;
char buffer[TCPPACKETSIZE];
System_printf("tcpWorker: start clientfd = 0x%x\n", clientfd);
while ((bytesRcvd = recv(clientfd, buffer, TCPPACKETSIZE, 0)) > 0) {
bytesSent = send(clientfd, buffer, bytesRcvd, 0);
if (bytesSent < 0 || bytesSent != bytesRcvd) {
System_printf("Error: send failed.\n");
break;
}
}
System_printf("tcpWorker stop clientfd = 0x%x\n", clientfd);
close(clientfd);
}
/*
* ======== tcpHandler ========
* Creates new Task to handle new TCP connections.
*/
Void tcpHandler(UArg arg0, UArg arg1)
{
int status;
int clientfd;
int server;
struct sockaddr_in localAddr;
struct sockaddr_in clientAddr;
int optval;
int optlen = sizeof(optval);
socklen_t addrlen = sizeof(clientAddr);
Task_Handle taskHandle;
Task_Params taskParams;
Error_Block eb;
server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (server == -1) {
System_printf("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(arg0);
status = bind(server, (struct sockaddr *)&localAddr, sizeof(localAddr));
if (status == -1) {
System_printf("Error: bind failed.\n");
goto shutdown;
}
status = listen(server, NUMTCPWORKERS);
if (status == -1) {
System_printf("Error: listen failed.\n");
goto shutdown;
}
optval = 1;
if (setsockopt(server, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
System_printf("Error: setsockopt failed\n");
goto shutdown;
}
while ((clientfd =
accept(server, (struct sockaddr *)&clientAddr, &addrlen)) != -1) {
System_printf("tcpHandler: Creating thread clientfd = %d\n", clientfd);
/* Init the Error_Block */
Error_init(&eb);
/* Initialize the defaults and set the parameters. */
Task_Params_init(&taskParams);
taskParams.arg0 = (UArg)clientfd;
taskParams.stackSize = 1280;
taskHandle = Task_create((Task_FuncPtr)tcpWorker, &taskParams, &eb);
if (taskHandle == NULL) {
System_printf("Error: Failed to create new Task\n");
close(clientfd);
}
/* addrlen is a value-result param, must reset for next accept call */
addrlen = sizeof(clientAddr);
}
System_printf("Error: accept failed.\n");
shutdown:
if (server > 0) {
close(server);
}
}
/*
* ======== main ========
*/
int main(void)
{
/* Call board init functions */
Board_initGeneral();
Board_initGPIO();
Board_initEMAC();
System_printf("Starting the TCP Echo example\nSystem provider is set to "
"SysMin. Halt the target to view any SysMin contents in"
" ROV.\n");
/* SysMin will only print to the console when you call flush or exit */
System_flush();
/* Start BIOS */
BIOS_start();
return (0);
}
Hi Sergey,
Great, so is it working for you now? Please click the "This resolved my issue" button if so.
Best,
Brandon
Hi Brandon:
This is working for me , but I am still cannot detect cable removal.
What is my options ?
Can I have access to interrupt on emac on link up/down ?
If I need to open another issue let me know I will close this one and create new issue.
Thanks
Hi,
Yes, it's best to open another issue for organization, and to click the resolved issue button to close this thread.
In the meantime please refer to this thread before posting to see if it accomplishes what you're after: https://e2e.ti.com/support/microcontrollers/other/f/908/p/800445/2963424#2963424
This thread should also be helpful: https://e2e.ti.com/support/processors/f/791/p/681542/2512163#2512163
Thanks,
Brandon