#1
  1. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    18
    Rep Power
    0

    Smile socket operation on something not socket


    :confused:
    #include <winsock2.h>
    #include <stdio.h>
    #include <string.h>

    int startupServerForListening(unsigned short port);
    void shutdownServer(int socket) ;

    HANDLE threadHandle;

    int numConnect = 0;
    int maxConnect = 6;
    int mySocket;
    int nBytes;

    char strServer[100] = "Hello Clients!!";
    char *clientArrays[6];
    struct hostent *client_entry;
    char hostname[80];
    char *clientName;

    HANDLE mutexHandle;

    FD_SET masterSet;

    bool gQuitFlag = false;

    void acceptingThreadProcedure(int* serverSocket,struct sockaddr_in client )
    {
    int nBytesSend;

    bool firstConn = true;

    // copy my socket over to a local variable
    int mySocket = *serverSocket;

    SOCKET clientiparray[6];
    for (;;)
    {
    int size = sizeof(struct sockaddr);
    // accept a client like normal
    unsigned int clientSocket = accept(mySocket,(struct sockaddr*)&client,&size);
    // make sure things are ok
    if (clientSocket == SOCKET_ERROR)
    {


    printf("Accept Failed!\n");
    printf("%d\n",WSAGetLastError());

    gQuitFlag = true;
    return;

    } else
    {

    WaitForSingleObject(mutexHandle, INFINITE);

    FD_SET(clientSocket, &masterSet);

    client_entry = gethostbyname(clientName);
    if (client_entry == 0)
    {
    printf("Error gethostbyname:%d\n",WSAGetLastError());

    }else
    {
    numConnect++;
    printf("Connection NO.%d\n",numConnect);

    unsigned int addrLen = sizeof(client.sin_addr);
    printf( "Incoming Address %d IP: %s\n" ,numConnect,inet_ntoa(client.sin_addr));
    clientArrays[numConnect] = inet_ntoa(client.sin_addr);
    printf("clientArray %s\n",*(&clientArrays[numConnect]));
    ReleaseMutex(mutexHandle);
    }
    printf("client on %d connected\n", clientSocket);
    if (firstConn)
    {
    //Broadcast send
    for (int i=0;i < numConnect;i++)
    {
    nBytesSend = sizeof(strServer);
    clientiparray[i] = inet_addr(clientArrays[numConnect]);
    nBytesSend = send(clientiparray[i],strServer,nBytesSend,0);


    printf("masterset fd_set:%d\n",masterSet.fd_array[i]);
    if (nBytesSend == SOCKET_ERROR)
    {
    // lock the mutex
    WaitForSingleObject(mutexHandle, INFINITE);
    printf("Some error from winsock :%d\n",WSAGetLastError());
    ReleaseMutex(mutexHandle);

    }
    }
    }

    }
    }
    }


    void main()
    {
    printf( "--------------------------------------\n" );
    printf( "|| Server v0.2beta ||\n");
    printf( "|| ||\n");
    printf( "--------------------------------------\n") ;

    // Startup our network as usual.

    // the socket my server will use for listening
    int serverSocket;


    // startup my network utilities with my handy functions
    serverSocket = startupServerForListening(7654);

    // check for errors
    if (serverSocket == -1)
    {
    printf("Network Startup Failed!\nProgram Terminating\n");
    return;
    }

    // create our mutex and our thread and receive handles for both.

    // create the mutex
    mutexHandle = CreateMutex(NULL, false, NULL);
    if (mutexHandle == NULL)
    {
    printf("Error creating mutex\n");
    shutdownServer(serverSocket);
    return;
    }

    // create the thread
    int threadId;
    threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)acceptingThreadProcedure, &serverSocket, 0, (LPDWORD)&threadId);
    if (threadHandle == NULL)
    {
    printf("Could not start acceptance thread\n");
    shutdownServer(serverSocket);
    return;
    }


    // sleep the main() so the acceptance thread has time to start ... this is cheesy
    Sleep(100);

    // Now that that is all over with, it's down to business.

    // It's always a good idea to initialize our structures before we access them, so let's zero our masterSet.
    FD_ZERO(&masterSet);

    // the main loop ... run forever
    for (;;)
    {
    if (gQuitFlag)
    {
    break;
    }

    // lock the mutex
    WaitForSingleObject(mutexHandle, INFINITE);

    // make the polling set and copy everything from masterSet
    FD_SET pollingSet = masterSet;

    // unlock the mutex
    ReleaseMutex(mutexHandle);

    // check if our set is empty
    if (pollingSet.fd_count == 0)
    {
    continue;
    }

    // select() has 5 parameters. They are:
    // - the number of file descriptors
    // - a FD_SET to check for readability
    // - a FD_SET to check for writeability
    // - a FD_SET to check for errors
    // - a wait time

    // The wait time is a timeval structure. You can set the number of seconds and microseconds for select
    // to wait before it times out. This can be useful in specialized circumstances, but we will just make it 0
    // so it times out immediately and returns.

    // the wait time
    timeval waitTime;
    waitTime.tv_sec = 0;
    waitTime.tv_usec = 0;

    // and select(). select from the polling set using fd_count as the number of sockets. We do not have a
    // write set nor an errors set, so just pass NULL for them.

    int result = select(pollingSet.fd_count, &pollingSet, NULL, NULL, &waitTime);

    // The return value for select() is the number of sockets that have data ready to read. Like most our
    // networking function, if an error occurred, this value will be SOCKET_ERROR, otherwise it will indicate
    // success.

    // But select() can return 0 if there was no data to be read. In this case, just continue on with the
    // rest of the program.

    // check for no sockets with data
    if (result == 0)
    {
    // no sockets have data
    continue;
    }

    // check for errors
    if (result == SOCKET_ERROR)
    {
    printf("Error in select()\n");
    continue;
    }

    // Now that we have the polling set that contains just the sockets that have data, let's step through
    // the list of sockets and read from them all.

    // for every socket in my polling set
    for (unsigned int i = 0; i < pollingSet.fd_count; i++)
    {

    // access the socket list directly using the fd_array member of the FD_SET
    unsigned int clientSocket = pollingSet.fd_array[i];

    // We will be using the same variable length data system that we implemented in tutorial #4.
    // So we need a few variables to facilitate the communication.

    // the number of bytes we received
    int nBytes;

    // a buffer to hold my data
    #define MAX_MESSAGE_SIZE 4096
    char buffer[MAX_MESSAGE_SIZE];

    //send to client first
    //sendtoall(numConnect);

    // the size of the message that is being sent
    unsigned long messageSize;

    // receive the message size first
    nBytes = recv(clientSocket, (char*)&messageSize, sizeof(messageSize), 0);

    // check for errors
    if (nBytes == SOCKET_ERROR)
    {

    // Uh Oh! We have our first real use of error handling! Something can happen here that is
    // pretty significant. Let's grab the error number from winsock.
    int error = WSAGetLastError();

    // handle the dropped connection
    if (error == WSAECONNRESET)
    {

    // When we receive this error. Just get a lock on the master set, and remove this socket from
    // set using the FD_CLR() macro.

    // lock our mutex
    WaitForSingleObject(mutexHandle, INFINITE);

    // remove the socket from our master set
    FD_CLR(clientSocket, &masterSet);

    // unlock our mutex
    ReleaseMutex(mutexHandle);

    // close the socket on our side, so our computer cleans up properly
    closesocket(clientSocket);

    // a quick message
    printf("client on %d disconnected\n", clientSocket);

    // move on to the next client
    continue;

    }
    }



    if (nBytes == 0)
    {
    // lock our mutex
    WaitForSingleObject(mutexHandle, INFINITE);

    FD_CLR(clientSocket, &masterSet);
    ReleaseMutex(mutexHandle);

    closesocket(clientSocket);

    printf("client on %d disconnected\n", clientSocket);

    continue;
    }
    messageSize = ntohl(messageSize);

    nBytes = recv(clientSocket, buffer, messageSize, 0);

    if (nBytes == SOCKET_ERROR)
    {
    printf("Recv Failed!\n");
    gQuitFlag = true;
    break;
    }

    buffer[messageSize] = '\0';

    printf("Message Received from client on %d : %s\n", clientSocket, buffer);


    }
    }

    shutdownServer(serverSocket);

    printf("Press Enter to Exit ...\n");
    getchar();


    }

    int startupServerForListening(unsigned short port)
    {
    int error;
    WSAData wsaData;
    if ((error = WSAStartup(MAKEWORD(2, 2), &wsaData)) == SOCKET_ERROR)
    {
    printf("Could Not Start Up Winsock!\n");
    return -1;
    }
    mySocket = socket(AF_INET, SOCK_STREAM, 0);
    if (mySocket == SOCKET_ERROR)
    {
    printf("Error Opening Socket!\n");
    return -1;
    }
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = INADDR_ANY;
    if (bind(mySocket, (sockaddr*)&server, sizeof(server))
    {
    printf("Bind Failed!\n");
    closesocket(mySocket);
    return -1;
    }
    if (getsockname(mySocket,(struct sockaddr*)&server,(int*)sizeof(server))==0)
    {
    perror("getsockname:");
    printf("getsockname Fail!!!\n");
    }
    if (gethostname(hostname,sizeof(hostname)))
    {
    printf("Error gethostname:%d\n",WSAGetLastError());
    }else
    {
    printf("Host name: %s\n",hostname);

    }
    if (listen(mySocket, maxConnect) == SOCKET_ERROR)
    {
    printf("Listen Failed!\n");
    closesocket(mySocket);
    return -1;
    }

    printf("Server Started\n");

    return mySocket;
    }

    void shutdownServer(int socket)
    {

    // kill my thread and my handle
    WaitForSingleObject(threadHandle, INFINITE);
    CloseHandle(threadHandle);
    CloseHandle(mutexHandle);

    // close our socket
    closesocket(socket);

    // shut down winsock
    WSACleanup();

    printf("Server Shutdown\n");
    }
  2. #2
  3. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    18
    Rep Power
    0
    I apply code (multihost from www.gametutorials.com) what I want to do is to make multithread server can send broadcast to all clients and when clients send some messages to server,server will broadcast the message to all. I use VC++ 6.0 and winsock2
    An error occur: socket operation on something not socket
    I think it's about fd_array that I make mistake on.Any one have suggestion??
  4. #3
  5. No Profile Picture
    Junior Member
    Devshed Newbie (0 - 499 posts)

    Join Date
    Sep 2003
    Posts
    18
    Rep Power
    0
    And I have another important question
    "Am I too wrong to get someone's code and apply it to serve my purpose? "
  6. #4
  7. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    listen im not trying be a jerk, but you post like 6 pages of code that isnt formatted and you give us no clue as to where the error has occurred. to post code, use the [ code ] tags please. all i can say is that you didnt create the socket correctly, or have mixed up the variables. The error your recieving is b/c you have either called: listen,recv,send,accept or some variation on what you think is a socket, but actually isnt. either the creation of the socket failed, or you didnt pass the socket correctly etc. please format your code and tell us where the error occurs if you want more help.

IMN logo majestic logo threadwatch logo seochat tools logo