Select Winsock Error 10038

Started by
8 comments, last by Xloner12 16 years ago
Ok so I know that to use select to you have to do FD_ZERO and FD_SET before each time now I'll post my c code in a second but basicly my server application will accept the first client and every thing works fine. When I go to connect my second client it gives me a 10038 error. Now the connection with the first client stays open and working even after the error but when ever I try to get a second one connected it always drops. Every time my loop cycles I have it do a routine for FD_ZERO and FD_SET and Im still getting this. Below is my server code. The offending issue happens during the first scan of select on the second connected client when it checks to see if theres any thing to read. The second client gets connected and even gets a string back from the server saying its connected but its when I do a select on it in the START SELECT CONNECTED PHASE for the first time that it craps out. Any help would be apperciated. Thanks,
[source lang=c]
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winbase.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <conio.h>
#include <time.h>
#include "../../library/fileOperations.h"

#define MAXSOCKETS 5
#define DEFAULT_PORT "27052"
#define MAX_BUFFER 500
int error_WSAStartup;
int error_bind;
int error_listen;
int error_shutdown;
int error_getaddrinfo;
int error_recv;
int lineNumber = 0;
int lineNumber2 = 0;
char hold[5];



int main (int argc, char **argv)
{
/**********VAR PHASE********************************/

  WSADATA info_WSADATA;
  SOCKET listenSocket = INVALID_SOCKET;
  SOCKET clientSocket[MAXSOCKETS];


  struct addrinfo *result = NULL;
  struct sockaddr_in address_listenSocket;
  struct sockaddr_in serverAddress;
  struct fd_set clientSocketSet[MAXSOCKETS];
  struct fd_set listenSocketSet;
  struct timeval maxTime;

  char send_buffer[MAX_BUFFER] = "Connection Established";
  char recv_buffer[MAX_BUFFER];
  char hold[10];

  int sendResult;
  int recv_bufferLen = MAX_BUFFER;
  int clientConnected = 0;
  
  serverAddress.sin_addr.s_addr = INADDR_ANY;
  serverAddress.sin_family = AF_INET;
  serverAddress.sin_port = htons(10023);


/****** Work Phase ***********************************/

  maxTime.tv_sec = 2;
  maxTime.tv_usec = 0;
  



  error_WSAStartup = WSAStartup(MAKEWORD(2,2), &info_WSADATA);
  if(error_WSAStartup != 0)
    {
      printf("WSAStartup Failed: %d\n",error_WSAStartup);
      exit(0);
    }
  


  listenSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  if(listenSocket == INVALID_SOCKET)
    {
      printf("Error at socket(): %ld\n", WSAGetLastError());
      freeaddrinfo(result);
      WSACleanup();        
      exit(0);
    }
  


  error_bind = bind(listenSocket,(LPSOCKADDR)&serverAddress,sizeof(serverAddress));
  if(error_bind == SOCKET_ERROR)
    {
      printf("bind failed: %d\n", WSAGetLastError());
      freeaddrinfo(result);
      closesocket(listenSocket);
      WSACleanup();
      exit(0);
    }

  
  
  error_listen = listen(listenSocket,SOMAXCONN);
  if(error_listen == SOCKET_ERROR)
    {
      printf("Listen Failed: %d\n", WSAGetLastError());
      closesocket(listenSocket);
      WSACleanup();
      exit(0);
    }

/*EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
                          MAIN WHILE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE*/ 
  int selectReturn = 0;
  while(1)
    {

/*|||||||||||||||||||||||||||START SELECT LISTEN PHASE ||||||||||||||||||||||||*/
      FD_ZERO(&listenSocketSet);
      FD_SET(1,&listenSocketSet);
      listenSocketSet.fd_array[0] = listenSocket;
      
      
      selectReturn = select(FD_SETSIZE,&listenSocketSet,NULL,NULL,&maxTime);
      printf("listen Select\n");
      if(selectReturn == SOCKET_ERROR)
        {
          printf("select listen failed: %d\n",WSAGetLastError());
          printf("selectReturn: %d\n",selectReturn);
          closesocket(listenSocket);
          WSACleanup();
          exit(0);
        }
      else
        {
          if(selectReturn == 1)
            {
                clientSocket[clientConnected] = accept(listenSocket,NULL,NULL);
                clientConnected = clientConnected + 1;
                if(clientSocket[clientConnected-1] == INVALID_SOCKET)
                  {
                    printf("Accept Failed: %d\n",WSAGetLastError());
                    closesocket(listenSocket);
                    clientConnected = clientConnected - 1;
                  }
                sendResult = send(clientSocket[clientConnected-1],send_buffer,strlen(send_buffer)+1,0);
                if(sendResult == SOCKET_ERROR)
                  {
                    printf("send failed: %d\n",WSAGetLastError());
                    closesocket(clientSocket[clientConnected-1]);
                    clientConnected = clientConnected - 1;
                  }
            }
        }
/*|||||||||||||||||||||||||||END SELECT LISTEN PHASE ||||||||||||||||||||||||*/


/*|||||||||||||||||||||||||||START SELECT CONNECTION PHASE ||||||||||||||||||||||||*/
      if(clientConnected > 0)
        {


          lineNumber = 0;
          while(lineNumber < clientConnected)
            {
              lineNumber2 = 0;
              while(lineNumber2 < clientConnected)
                {
                  FD_ZERO(&clientSocketSet[lineNumber2]);
                  FD_SET(1,&clientSocketSet[lineNumber2]);
                  clientSocketSet[lineNumber2].fd_array[lineNumber2] = clientSocket[lineNumber2];
                  lineNumber2++;
                }
          
              selectReturn = 0;
              selectReturn = select(FD_SETSIZE,&clientSocketSet[lineNumber],NULL,NULL,&maxTime);
              printf("Connection Select %d\n",lineNumber);
              if(selectReturn == SOCKET_ERROR)
                {
                  printf("select connection Failed: %d\n",WSAGetLastError());
                  printf("selectReturn: %d\n",selectReturn);
                  closesocket(clientSocket[lineNumber]);
                  clientConnected = clientConnected - 1;
                }
              else
                {
                  if(selectReturn == 1)
                    {
                      error_recv = recv(clientSocket[lineNumber],recv_buffer,MAX_BUFFER,0);
                      if(error_recv  == SOCKET_ERROR)
                        {
                          printf("Recive Failed: %d\n",WSAGetLastError());
                          closesocket(clientSocket[lineNumber]);
                          clientConnected = clientConnected - 1;
                        }
                      printf("%s\n",recv_buffer);
                    }
                }
              lineNumber++;
            }
        }
    }
/*|||||||||||||||||||||||||||END SELECT CONNECTION PHASE ||||||||||||||||||||||||*/

/*EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
                        END  MAIN WHILE
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE*/
 
}

Do or do not there is no try -yoda
Advertisement
Error 10038 is a WSAENOTSOCK, which according to MSDN means that "One of the descriptor sets contains an entry that is not a socket."

This problem could stem from the way you're using FD_SET. When you add a socket to the fd_set use
FD_SET(socket, &listenSocketSet);

Never manipulate the fd_count and fd_array members of the fd_set directly.
Select returns 0 when it times out, you're not taking that into consideration. It could be the problem. Read above.

[Edited by - xor on April 16, 2008 10:00:19 AM]
If I set FDCOUNT to 1 and then do FD_SET(FDCOUNT,&listenSocketSet) im still stating that fd_set sets aside one array unit for listenSocketSet. Besides the application listens and accepts fine.

As for not stating that if it returns zero i kinda do in a round about way. If it returns zero it should just fall though and continue with the rest of the program which would not prodcue the invalid socket type error that im getting.
Do or do not there is no try -yoda
/*|||||||||||||||||||||||||||START SELECT CONNECTION PHASE ||||||||||||||||||||||||*/      if(clientConnected > 0)        {          lineNumber = 0;          while(lineNumber < clientConnected)            {              lineNumber2 = 0;              while(lineNumber2 < clientConnected)                {                  FD_ZERO(&clientSocketSet[lineNumber2]);

If I understand correctly what you're trying to do, that FD_ZERO should be outside that while.



selectReturn = select(FD_SETSIZE,&clientSocketSet[lineNumber],NULL,NULL,&maxTime);              printf("Connection Select %d\n",lineNumber);              if(selectReturn == SOCKET_ERROR)                {                  printf("select connection Failed: %d\n",WSAGetLastError());                  printf("selectReturn: %d\n",selectReturn);                  closesocket(clientSocket[lineNumber]);                  clientConnected = clientConnected - 1;                }              else                {                  if(selectReturn == 1)

Again, if I understand what you're trying to do here, the selectReturn value might be more then just 1.
I actually moved the FD_ZERO and FD_SET into the loop before I posted it. If its out side of that loop its the same result. Also the error drops out when you check to see if selectReturn is == to SOCKET_ERROR, if its more then one it should only be say like 2 or 3 and should make it past this part. It shouldn't be equal to SOCKET_ERROR which is whats coming back.
Do or do not there is no try -yoda
Quote:Original post by Xloner12
If I set FDCOUNT to 1 and then do FD_SET(FDCOUNT,&listenSocketSet) im still stating that fd_set sets aside one array unit for listenSocketSet. Besides the application listens and accepts fine.

But... but you're using undocumented implementation details to do something and it's not working. I would argue that the application is not listening and not working fine, which is why you've posted here.

Consider this.
     FD_SET(1,&listenSocketSet);
Do you realize that you've just asked select() to listen on stdout? Is that what you really want? I suspect what you meant to say was
     FD_SET(listenSocket, &listenSocketSet);
followed by something like
     selectReturn = select(listenSocket+1, &listenSocketSet,NULL,NULL,&maxTime);


--smw

Stephen M. Webb
Professional Free Software Developer

FD_SET macro takes two var's

One is how many file sets and the second is the File set theme selves. I dont belive but could be wrong that the 1 is standing for stdout. when I pass the number one it just states that there will only be one file descriptor.

Am I wrong on this?
Do or do not there is no try -yoda
From the MSDN entry on select:
Quote:
FD_SET(s, *set)
Adds descriptor s to set.

Notice it does not say s number of descriptors. It adds the descriptor s to the set.
Ok I see, thanks every one. I just tested it out and now its working, simitanous connections. Thanks to every one, this is why I love this board. Thanks again.

[Edited by - Xloner12 on April 16, 2008 2:03:28 PM]
Do or do not there is no try -yoda

This topic is closed to new replies.

Advertisement