🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.internet.socket
Article #1908

Re: select returns 10022 invalid argument error

#1908
From: jer
Date: Thu, 28 Sep 2006 17:11
209 lines
7629 bytes
>> Before the sendto function I always use select to determine if the socket
>>is writable.
>That is generally not a good idea.  You should just call sendto() by itself,
>and let it report an error if it cannot send.

I'll give this a shot.

>> However, intermittently, the select statement times out (I set it to
>> a 3 sec timeout).  When this happens I skip the sendto function and try
>> the select again. At this point, select returns SOCKET_ERROR and
>> I get a 10022 error (invalid argument) when I call WSAGetLastError().
>From the select() documentation:
>WSAEINVAL
>The timeout value is not valid, or all three descriptor parameters were
>NULL.

>Please show your actual socket code.

See below.

>> Then I tried pinging localhost and I get destination unreachable.
>You probably blew up the TCP/IP stack altogether.  Pinging the localhost
>should never fail when TCP/IP is working properly.

Yeah, somehow I've managed to hang TCP/IP. I wonder if there's a way to
restart or reset TCP/IP without rebooting windows?

Here's some of my code.

//This is the code I use to set up the socket for sending data
//The parameters that are passed into the function are global,
//and are used in the send thread, see below.
int Start_UDP_Sock_Send(int* sockfd,
                     struct sockaddr_in* their_addr,
                     char* ip_addr,
                     int send_port)
{
   struct hostent *he;
   WSADATA wsaData;
   int error_status = 0;
   struct sockaddr_in my_addr;

   char host_name[80];

   //Begin setting up network socket
   if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
   {
      return error_status = -1;
   }

   //Set the address of the computer you want to send data to
   he = gethostbyname(ip_addr);

   //SOCK_DGRAM is used to set up a UDP socket
   if ((*sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
   {
      return error_status = -2;
   }

   //Next four lines set up network parameters
   (*their_addr).sin_family = AF_INET;     // host byte order
   (*their_addr).sin_port = htons(send_port); // short, network byte
order
   (*their_addr).sin_addr = *((struct in_addr *)he->h_addr);
   memset(&((*their_addr).sin_zero), '\0', 8); // zero the rest of the
struct

   //used to bind to a specific network interface on local pc
   my_addr.sin_family = AF_INET;         // host byte order
   my_addr.sin_port = 0;                 // short, network byte order
   if (strcmp(ip_addr, "10.100.4.200") == 0)
   {
      my_addr.sin_addr.s_addr = inet_addr("10.100.4.201");
   }
   else if (strcmp(ip_addr, "10.100.4.201") == 0)
   {
      my_addr.sin_addr.s_addr = inet_addr("10.100.4.200");
   }
   else if (strcmp(ip_addr, "localhost") == 0)
   {
      my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
   }
   memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct

   if((bind(*sockfd, (struct sockaddr *)&my_addr, sizeof(struct
sockaddr)))==SOCKET_ERROR)
   {
      return error_status = -3;
   }

   return error_status;
}

//This function runs in a separate thread. It sends data on
//the socket set up above.
int __fastcall send_thread_function(LPVOID lpParam)
{
   int error_value = 0;

   char loc_send_buf[1024];
   memset(loc_send_buf, 0, 1024);

   //Variables for sleep timer resolution
   TIMECAPS tc;
   timeGetDevCaps(&tc, sizeof(TIMECAPS));
   //Set the resolution of the timer
   timeBeginPeriod(tc.wPeriodMin);

   int send_cnt = 0;

   //used for storing the pc time
   struct time pc_time;

   fd_set writefds;
   struct timeval tv;
   int sel_value = 0;
   // wait until either socket is ready to send or time out in 3
seconds
   tv.tv_sec = 3;
   tv.tv_usec = 0;

   FD_ZERO(&writefds);
   FD_SET(sockfd_send, &writefds);

   FILE* test_fptr;
   //write debug data to a text file
   test_fptr = fopen("C:\\send_log.log", "a+t");

   int error_code = 0;

   gettime(&pc_time);
   if (test_fptr != NULL)
   {
      //write data
      fprintf(test_fptr, "Started Send Thread ***** at: ");
      fprintf(test_fptr, "%02d:%02d:%02d:%d\n", pc_time.ti_hour,
pc_time.ti_min, pc_time.ti_sec, pc_time.ti_hund);
      fclose(test_fptr);
   }

   //This function runs in a separate thread. It's used to send data
   for(;;)
   {
      memset(loc_send_buf, 0, 1024);
      //memcpy send data out of the global buffer
      memcpy(loc_send_buf, glob_send_buf, 1024);

      //Use select to time out if data is not ready to be sent
      sel_value = select(2, NULL, &writefds, NULL, &tv);
      if (sel_value == 0)
      {
         gettime(&pc_time);
         //write debug data to a text file
         test_fptr = fopen("C:\\send_log.log", "a+t");
         if (test_fptr != NULL)
         {
            //write data
            fprintf(test_fptr, "send select time out at: ");
            fprintf(test_fptr, "%02d:%02d:%02d:%d\n", pc_time.ti_hour,
pc_time.ti_min, pc_time.ti_sec, pc_time.ti_hund);
            fclose(test_fptr);
         }
         Sleep(3000);
      }
      else if (sel_value == SOCKET_ERROR)
      {
         error_code = WSAGetLastError();

         gettime(&pc_time);
         //write debug data to a text file
         test_fptr = fopen("C:\\send_log.log", "a+t");
         if (test_fptr != NULL)
         {
            //write data
            fprintf(test_fptr, "select error: %d at: ", error_code);
            fprintf(test_fptr, "%02d:%02d:%02d:%d\n", pc_time.ti_hour,
pc_time.ti_min, pc_time.ti_sec, pc_time.ti_hund);
            fclose(test_fptr);
         }
         Sleep(3000);
      }
      else
      {
         error_value = sendto(sockfd_send,
                              loc_send_buf,
                              616,
                              0,
                              (SOCKADDR *)&their_addr_send,
                              sizeof(their_addr_send));

         if (error_value > 0)
         {
            send_cnt++;
            Sleep(5);
         }
         else
         {
            Sleep(5000);
         }
      }
   }
   return 0;
}

I have code that I use to receive data as well. I can put this code up
if you think it would help. Your first reply has me thinking of a few
things to try out in the mean time. Thanks so much for your help!
Jer
Technical Details
Message-ID: <1159463517.999207.75630@e3g2000cwe.googlegroups.com>
Path: arc1-ca.pugleaf.net!g2news2.google.com!postnews.google.com!e3g2000cwe.googlegroups.com!not-for-mail
References: <1159392295.406227.295400@e3g2000cwe.googlegroups.com> <451b09bf$1@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 11508e,65957817ea9a74e3
X-Google-Attributes: gid11508e,public
X-Google-Language: ENGLISH,ASCII-7-bit
Path: arc1-ca.pugleaf.net!g2news2.google.com!postnews.google.com!e3g2000cwe.googlegroups.com!not-for-mail
From: "jer" <jer_bred_guy@yahoo.com>
Newsgroups: borland.public.cppbuilder.internet.socket
Subject: Re: select returns 10022 invalid argument error
Date: 28 Sep 2006 10:11:58 -0700
Organization: http://groups.google.com
Lines: 210
Message-ID: <1159463517.999207.75630@e3g2000cwe.googlegroups.com>
References: <1159392295.406227.295400@e3g2000cwe.googlegroups.com>
   <451b09bf$1@newsgroups.borland.com>
NNTP-Posting-Host: 205.175.225.24
Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
X-Trace: posting.google.com 1159463522 2395 127.0.0.1 (28 Sep 2006 17:12:02 GMT)
X-Complaints-To: groups-abuse@google.com
NNTP-Posting-Date: Thu, 28 Sep 2006 17:12:02 +0000 (UTC)
In-Reply-To: <451b09bf$1@newsgroups.borland.com>
User-Agent: G2/1.0
X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1),gzip(gfe),gzip(gfe)
Complaints-To: groups-abuse@google.com
Injection-Info: e3g2000cwe.googlegroups.com; posting-host=205.175.225.24;
   posting-account=m8Ijew0AAAA3kQiEKttGzmZq2gnboAPt