tcp accept error...

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

", 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

", 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

", 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

", getErrno());
closesocket(sock);
return;
}

#ifdef DEBUG
printf("MODBUSTCP: ready on port: %d

", 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

", err/getErrno()/);
closesocket(sock);
continue; //return;
}

  result = recv(fd, rcvData, RCV_BUFFER_SIZE, 0);
  if (result < 0)
  {
    printf("MODBUSTCP: recv(%d,,%d) failed: %d

", (int)sock, RCV_BUFFER_SIZE, getErrno());
closesocket(sock);
continue;
}
++CNT;
printf("MODBUSTCP: CNT %d, received[%d] TCP '%c' command.
", 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'

", rcvData[0], rcvData[1], rcvData[2]);
}
}

} while(1);

}

//------------------------------------------------

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
", 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).

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
", 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 (&amp;read_set);
    FD_SET (s1, &amp;read_set);
    FD_SET (s2, &amp;read_set);



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



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



    if (FD_ISSET(s2, &amp;read_set))
    {
        -- socket 2 has data available --
    }
}

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 *)&amp;clientSocket, &amp;szclientSocket);
    #else
    fd=accept(sock, &amp;clientSocket, &amp;szclientSocket);
    #endif
    if(fd&lt;0)
    {
      err=getErrno();
      printf("MODBUSTCP: accept failure: errno: %d

", err/getErrno()/);
tx_thread_sleep(NABspTicksPerSecond); // wait for 1 sec for next try
}
} while( (fd<0)&&(err==11)&&(retrycounter++

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.

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:

/usr/arm-elf/include/sys/errno.h
or

For NET+OS, use