Home/Support/Support Forum/tcp accept error...
Welcome to Digi Forum, where you can ask questions and receive answers from other members of the community.

tcp accept error...

0 votes
Hi,

I'm trying trun tcpserver code for DC-ME-NET dev. kit.
Accept command returns error always (first error code:11, and at the next tries returns error code:9)

The code below, how can i establish the tcp connection?

//

void modbustcpServer(unsigned long thread_input)
{
long sock, fd; /* socket descriptor */
struct sockaddr_in serverSocket, clientSocket; /* Internet endpoint address */
int result, szserverSocket, szclientSocket;
int block=1;
char rcvData[RCV_BUFFER_SIZE];
//char sendData[250];
unsigned int CNT = 0;
unsigned int old_priority;
signed int err;

//open the TCP socket
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
printf("MODBUSTCP: socket failure: errno: %d\n", getErrno());
closesocket(sock);
return;
}

//Set Socket Option
result = setsockopt(sock, SOL_SOCKET, SO_NONBLOCK, (char *)&block, sizeof(block));
if (result < 0)
{
printf("MODBUSTCP: setsockopt SO_NONBLOCK failure: errno: %d\n", getErrno());
closesocket(sock);
return;
}

//bind SERVER socket to PortNumber, any IP
memset((void *)&serverSocket, 0, sizeof(serverSocket));
serverSocket.sin_family = AF_INET;
serverSocket.sin_addr.s_addr = htonl(INADDR_ANY); // client address
serverSocket.sin_port = htons(PortNumber);
#ifdef IAM_ENABLED
result=bind(sock, (struct sockaddr *)&serverSocket, sizeof(serverSocket));
#else
result=bind(sock, &serverSocket, sizeof(serverSocket));
#endif
if(result<0)
{
printf("MODBUSTCP: bind failure: errno: %d\n", getErrno());
closesocket(sock);
return;
}

// set up server socket to receive a connection backlog determines max length of queue for pending client connections
result = listen(sock, listenBacklog);
if(result<0)
{
// close socket and return indicating failure
printf("MODBUSTCP: listen failure: errno: %d\n", getErrno());
closesocket(sock);
return;
}

#ifdef DEBUG
printf("MODBUSTCP: ready on port: %d\n", PortNumber);
#endif

do
{
// accept client connection request
szclientSocket = sizeof (clientSocket);
#ifdef IAM_ENABLED
fd=accept(sock, (struct sockaddr *)&clientSocket, &szclientSocket);
#else
fd=accept(sock, &clientSocket, &szclientSocket);
#endif
if(fd<0)
{
err=getErrno();
printf("MODBUSTCP: accept failure: errno: %d\n", err/*getErrno()*/);
closesocket(sock);
continue; //return;
}

result = recv(fd, rcvData, RCV_BUFFER_SIZE, 0);
if (result < 0)
{
printf("MODBUSTCP: recv(%d,,%d) failed: %d\n", (int)sock, RCV_BUFFER_SIZE, getErrno());
closesocket(sock);
continue;
}
++CNT;
printf("MODBUSTCP: CNT %d, received[%d] TCP \'%c\' command.\n", CNT, result, rcvData[0]);

/* transmit command */
switch (rcvData[0])
{
case 'T':
tx_thread_priority_change(tx_thread_identify(), 4, &old_priority);
transmit_segments(fd, rcvData);
tx_thread_priority_change(tx_thread_identify(), old_priority, &old_priority);
break;

case 'R':
receive_segments(fd, result);
break;

case 'E':
case 'X':
case 'N':
break;

default:
if (result<20)
{
rcvData[result] = 0;
printf("MODBUSTCP: TCP data was '%d %d %d'\n", rcvData[0], rcvData[1], rcvData[2]);
}
}

} while(1);

}


//
asked Jul 27, 2007 in Linux by aslanbaris New to the Community (4 points)
recategorized Dec 18, 2013 by tuxembb

Please log in or register to answer this question.

6 Answers

0 votes
In looking at your code I see the following:

do
{
// accept client connection request
szclientSocket = sizeof (clientSocket);
#ifdef IAM_ENABLED
fd=accept(sock, (struct sockaddr *)&clientSocket, &szclientSocket);
#else
fd=accept(sock, &clientSocket, &szclientSocket);
#endif
if(fd<0)
{
err=getErrno();
printf("MODBUSTCP: accept failure: errno: %d\n", err/*getErrno()*/);
closesocket(sock);
continue; //return;
}


If the accept fails, you trash socket sock. Now on the next accept attempt, your socket is junk. So the second accept fails with a bad file number.

Now error 11 = operation pending
error 9 = bad file number

So I believe you need to check for the error number. If 11, try the accept again without trashing sock (you might want to put in a delay before trying again, also). If anything but error 11 AND NOT SUCCESS, feel free to delete sock and then return (you are done).
answered Jul 27, 2007 by sparkys_dad Community Contributor (99 points)
0 votes
Thank you very much for reply,

I've tried to re-accept, but i get error code 11 for all retries. And i can't find error codes in header or include files. ( I'm using Digi ESP for NET+OS Version: 1.1.1 )

//

..............................
..............................

do
{
// accept client connection request
szclientSocket = sizeof (clientSocket);

err=0;
retrycounter=0;
do
{
#ifdef IAM_ENABLED
fd=accept(sock, (struct sockaddr *)&clientSocket, &szclientSocket);
#else
fd=accept(sock, &clientSocket, &szclientSocket);
#endif
if(fd<0)
{
err=getErrno();
printf("MODBUSTCP: accept failure: errno: %d\n", err/*getErrno()*/);
tx_thread_sleep(NABspTicksPerSecond); // wait for 1 sec for next try
}
} while( (fd<0)&&(err==11)&&(retrycounter++<TCPIP_ACCEPT_RETRY_COUNT) );

if(fd<0) { closesocket(sock); return; }

..............................
..............................

} while(1);
//
answered Jul 30, 2007 by aslanbaris New to the Community (4 points)
0 votes
Hello

Unfortunately, I am going to have to ask what will seem like obviopus questions, as follows:

Are you sure you are binding to the correct port number to which your clients will be attampting to connect?

Are you sure that your clients are attempting to connect to the ip address and port number on which your device is listening?

I generally use some variation of network protocol analyzer to ensure that my innies and outies are correct.
answered Jul 30, 2007 by sparkys_dad Community Contributor (99 points)
0 votes
Hello

I will assume for the moment that you are building on gnu (from within ESP). I believe the error codes are located in the cygwin directory. They are (the error codes) located in either one of the following:

<your cygwin directory>/usr/arm-elf/include/sys/errno.h
or
<your cygwin directory/usr/include/sys/errno.h
answered Jul 30, 2007 by sparkys_dad Community Contributor (99 points)
0 votes
For NET+OS, use <your cygwin directory/usr/include/sys/errno.h
answered Jul 30, 2007 by charliek Veteran of the Digi Community (408 points)
0 votes
Quick fix: delete the lines:


//Set Socket Option
result = setsockopt(sock, SOL_SOCKET, SO_NONBLOCK, (char *)&block, sizeof(block));
if (result < 0)
{
printf("MODBUSTCP: setsockopt SO_NONBLOCK failure: errno: %d\n", getErrno());
closesocket(sock);
return;
}

When a socket is nonblocking, all socket functions will return immediately. So accept returns an error because, when you call it, there is no connection pending. Later, when you call "recv", it would most likely return a 0 immediately indicating, at that instant in time, there are no bytes pending. In order to use nonblocking sockets properly, you will need to poll the status of the sockets using some function, most likely the function "select".

I cut and paste an example of how to use select from the NetOS API doc below. You could google some other examples for using nonblocking sockets if you need more details as well.

fd_set read_set;



struct timeval wait;



for (;;)
{
wait.tv_sec = 1; -- wait for 1 second --
wait.tv_usec = 0;



FD_ZERO (&read_set);
FD_SET (s1, &read_set);
FD_SET (s2, &read_set);



nb = select (FD_SETSIZE, &read_set, (fd_set *) 0, (fd_set *) 0, &wait);
if (nb <= 0)
{
-- error occurred or timed out --
}



if (FD_ISSET(s1, &read_set))
{
-- socket 1 has data available --
}



if (FD_ISSET(s2, &read_set))
{
-- socket 2 has data available --
}
}
answered Aug 1, 2007 by ipark New to the Community (1 point)
...