This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Non-blocking BSD socket - fast reconnect problem

Hi

  • I'm having problem with forum. I can't post message with text and code.

  • I'm trying to implement non-blocking BDS sockets TCP server. I will not allow use of multiple clients. I'm using Keil 4.74 with Real Time OS.

    Socket is in blocking mode until client connection request is accepted. After that, socket mode is set to non-blocking.

    Server must replay to every client request. Events generated on server side are being immediately sent to connected client.

  • I must restart my demo board or perform reset with debugger to fix problem. When problem occurs, I can connect to server, but I'll not get response from server. TCP disconect seems OK in Wireshark.

    Problem occurs while performin bind(). I'm receiving error code -3 (SCK_EINVALIDPARA). I've tested code with TCP debug library and I'm getting BSD SOCKET PORT IN USE error.

    I've tried set socket to non-blocking immediately after socket() function, but this doesn't fix problem.

  • __task void bsd_tcp_server(void)
    { SOCKADDR_IN addr; unsigned long sck_mode = 1;

    int32_t sock, sd, res; char buf[256];

    while (1) { if ((sock = socket (AF_INET, SOCK_STREAM, 0)) > 0) { addr.sin_port = htons(1000); addr.sin_family = PF_INET; addr.sin_addr.s_addr = INADDR_ANY;

    if ((res = bind(sock, (SOCKADDR *)&addr, sizeof(addr))) == SCK_SUCCESS) { if ((res = listen(sock, 1)) == SCK_SUCCESS) { sd = accept(sock, NULL, NULL); closesocket(sock);

    if (sd > 0) { sock = sd;

    if (ioctlsocket (sock, FIO_DELAY_ACK, &sck_mode) == SCK_SUCCESS) { if (ioctlsocket (sock, FIONBIO, &sck_mode) == SCK_SUCCESS) { while (1) { res = recv(sock, buf, sizeof(buf), 0);

    if ((res <= 0) && (res != SCK_EWOULDBLOCK) && (res!=SCK_ELOCKED)) { break; }

    else if (res > 0) { // analyse request, send response // if send() returns error, close socket if (analyse_response(sock, (uint8_t *) buf, res) < 0) { close_nonblocking_socket(sock); break; } }

    os_dly_wait(25);

    // if there is pending event, perform send() // if send() returns error, close socket if (send_status_update(sock) < 0) { close_nonblocking_socket(sock); break; } } } } } } }

    closesocket(sock); } os_dly_wait(25); }
    }

  • __task void bsd_tcp_server(void)
    {
       SOCKADDR_IN addr;
       unsigned long sck_mode = 1;
    
       int32_t sock, sd, res;
       char buf[256];
    
       while (1)
       {
          if ((sock = socket (AF_INET, SOCK_STREAM, 0)) > 0)
          {
             addr.sin_port        = htons(1000);
             addr.sin_family      = PF_INET;
             addr.sin_addr.s_addr = INADDR_ANY;
    
             if ((res = bind(sock, (SOCKADDR *)&addr, sizeof(addr))) == SCK_SUCCESS)
             {
                if ((res = listen(sock, 1)) == SCK_SUCCESS)
                {
                   sd = accept(sock, NULL, NULL);
                   closesocket(sock);
    
                   if (sd > 0)
                   {
                      sock = sd;
    
                      if (ioctlsocket (sock, FIO_DELAY_ACK, &sck_mode) == SCK_SUCCESS)
                      {
                         if (ioctlsocket (sock, FIONBIO, &sck_mode) == SCK_SUCCESS)
                         {
                            while (1)
                            {
                               res = recv(sock, buf, sizeof(buf), 0);
    
                               if ((res <= 0) && (res != SCK_EWOULDBLOCK) && (res!=SCK_ELOCKED))
                               {
                                  break;
                               }
    
                               else if (res > 0)
                               {
                                  // analyse request, send response
                                  // if send() returns error, close socket
                                  if (analyse_response(sock, (uint8_t *) buf, res) < 0)
                                  {
                                     close_nonblocking_socket(sock);
                                     break;
                                  }
                               }
    
                               os_dly_wait(25);
    
                               // if there is pending event, perform send()
                               // if send() returns error, close socket
                               if (send_status_update(sock) < 0)
                               {
                                  close_nonblocking_socket(sock);
                                  break;
                               }
                            }
                         }
                      }
                   }
                }
             }
    
             closesocket(sock);
          }
          os_dly_wait(25);
       }
    }
    

  • Socket close function also needs time to complete. When the socket is in non-blocking mode, the function closesocket() needs additional calls until the function returns SCK_SUCCESS.