CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Dec 2005
    Posts
    114

    Winsock help needed NOW!

    I need to find out if data is available to be read from a socket before I read it with recv so I don't have to wait cuz I am gona port my server over from VB to C++ and I'ma gona have a thread that loops through multiple sockets and reads the data and if all the other sockets have to wait for one to recieve data then that is gona suck balls.

    So someone please help me to figure out how to retrieve if data is available from a socket.

  2. #2
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Winsock help needed NOW!

    [ Redirected thread ]

  3. #3
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Winsock help needed NOW!

    Quote Originally Posted by Guidosoft
    So someone please help me to figure out how to retrieve if data is available from a socket.
    You can use 'select()' for example...

  4. #4
    Join Date
    Dec 2005
    Posts
    114

    Re: Winsock help needed NOW!

    Can you please give me a code example and not just a link to MSDN?

    I just need an example of how to find out if I can read data from the socket. I don't need all that other stuff that I already know in the example.

  5. #5
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Winsock help needed NOW!

    Something like...
    Code:
    // Client send function
    int Send(void *pvBuffer, int iStillToSend)
    {
      int     iRC         = 0;
      int     iSendStatus = 0;
      timeval SendTimeout;
      char    *pBuffer    = static_cast<char *>(pvBuffer);
    
      fd_set fds;
    
      FD_ZERO(&fds);
      FD_SET(Socket, &fds);
    
      // Set timeout
      SendTimeout.tv_sec  = 0;
      SendTimeout.tv_usec = 250000;              // 250 ms
    
      // As long as we need to send bytes...
      while(iStillToSend > 0)
      {
        iRC = select(0, NULL, &fds, NULL, &SendTimeout);
    
        // Timeout
        if(!iRC)
          return -1;
    
        // Error
        if(iRC < 0)
          return WSAGetLastError();
    
        // Send some bytes
        iSendStatus = send(Socket, pBuffer, iStillToSend, 0);   // Socket is of type
                                                                // 'SOCKET' and is
                                                                // the current
                                                                // connection socket
    
        // Error
        if(iSendStatus < 0)
          return WSAGetLastError();
        else
        {
          // Update buffer and counter
          iStillToSend -= iSendStatus;
          pBuffer += iSendStatus;
        }
      }
    
      return 0;
    }

  6. #6
    Join Date
    Dec 2005
    Posts
    114

    Re: Winsock help needed NOW!

    Thanx but I need to find out if there is data available to be read from a socket this way I don't have to wait for the function. I can just know if there isn't data, and don't run the recv function. I can make a simple loop to go through multiple sockets and recieve data in the same thread without having to wait on one socket that doesn't have any available data to read.

  7. #7
    Join Date
    Mar 2005
    Posts
    137

    Re: Winsock help needed NOW!

    you can used the same code in the previous post to check that if socket has anything to receive by modifying the select() call from

    Code:
    iRC = select(0, NULL, &fds, NULL, &SendTimeout);
    to

    Code:
    iRC = select(0, &read_fds, &write_fds, NULL, &SendTimeout);
    Where read_fds contains all the sockets to recv() from and write_fds contains all the sockets to send() to. You can add a single socket to both FD_SETS and then when select() returns, use FD_ISSET() to check which set (read or write) has the socket set. If its read set then you can run recv() on that socket to receive the data.

    I think you need to read a bit on select() . Read the following link. It has an example too.

    http://beej.us/guide/bgnet/output/ht...ed.html#select

  8. #8
    Join Date
    Jan 2006
    Posts
    14

    Re: Winsock help needed NOW!

    Why dont you run the recv on a different thread? That thread will be blocked, but you can continue your work on the main thread.....

  9. #9
    Join Date
    Dec 2005
    Posts
    114

    Re: Winsock help needed NOW!

    Oh so your saying I should have 500 threads for each socket?

    That is retarded.


    I have 2 threads in my application.
    1. The GUI Thread - Handles all the GUI crap.
    2. The server thread - Handles all the sockets.

    I need to make sure that I don't have to wait on sockets. Thats why I am using select().

  10. #10
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: Winsock help needed NOW!

    Quote Originally Posted by Guidosoft
    Oh so your saying I should have 500 threads for each socket?

    That is retarded.


    I have 2 threads in my application.
    1. The GUI Thread - Handles all the GUI crap.
    2. The server thread - Handles all the sockets.

    I need to make sure that I don't have to wait on sockets. Thats why I am using select().
    Well...this raises another question...how many clients will connect to your server simultaneously? Usually, you don't want to handle them all in one thread but increase performance and scalability by using a multithreaded server...

  11. #11
    Join Date
    Dec 2005
    Posts
    114

    Re: Winsock help needed NOW!

    500 maximum. Thats why I don't want to use 500 threads. My poor little system can't handle 500 threads.

    O, and I have another problem.

    When my server accepts a connection, it closes the listening socket and then redoes the listening process by creating, binding, and listening.

    However it fails to bind and returns a WSAADDRINUSE error. I don't understand what is wrong. I closed the listening socket before I created a new one and bound it but it didn't bind I just get an error.

    PLEASE HELP ME!!!!

  12. #12
    Join Date
    Aug 2002
    Location
    Cluj-Napoca,Romania
    Posts
    3,496

    Re: Winsock help needed NOW!

    Quote Originally Posted by Guidosoft
    However it fails to bind and returns a WSAADDRINUSE error. I don't understand what is wrong. I closed the listening socket before I created a new one and bound it but it didn't bind I just get an error.
    This is a problem related to the TCP stack implementation. For different reasons, a stack implementation can choose to keep the port reserved/locked for a while after it is closed. The safest solution would be to change your design so that you do not need to close it, reopen it and bind it every time.

    Here is more information about the error you encounter:

    Quote Originally Posted by msdn
    Address already in use.
    Typically, only one usage of each socket address (protocol/IP address/port) is permitted. This error occurs if an application attempts to bind a socket to an IP address/port that has already been used for an existing socket, or a socket that was not closed properly, or one that is still in the process of closing. For server applications that need to bind multiple sockets to the same port number, consider using setsockopt (SO_REUSEADDR). Client applications usually need not call bind at all— connect chooses an unused port automatically. When bind is called with a wildcard address (involving ADSDR_ANY), a WAEADDRINUSE error could be delayed until the specific address is committed. This could happen with a call to another function later, including connect, listen, WSAConnect, or WSAJoinLeaf.
    Har Har

  13. #13
    Join Date
    Dec 2005
    Posts
    114

    Re: Winsock help needed NOW!

    OK, so I am only listening for 1 connections at a time. Now, after I accept,, how do I go back to listening on that port using the same listening socket? Hmm?

    I shouldn't have to reconfigure the whole design because I have a functions RefreshLSock() which basically does the close, create, bind and listen. I should just be able to change that function to make it just listen again.

    But how do I do that after accepting a connection?

    And how come when I click Stop in my server and then Run, it works fine? The stop button closes all the sockets!

    And what if I wanted to close, create, bind and listen each time? How would I go about unlocking and unreserving the port so I can?

    Also, one more problem?

    The select() function won't detect when telnet closes the connection or when any other client does it (I assume). How do I tell when the connection is closed because the function I made that uses select() woin't tell me and the function works flawlessly.

  14. #14
    Join Date
    Apr 2003
    Location
    kathmandu, nepal
    Posts
    1,570

    Re: Winsock help needed NOW!

    Hi Andreas,

    I used code provided by you a long time back and have found a little bug.

    Code:
    // Client send function
    int Send(void *pvBuffer, int iStillToSend)
    {
      int     iRC         = 0;
      int     iSendStatus = 0;
      timeval SendTimeout;
      char    *pBuffer    = static_cast<char *>(pvBuffer);
    
      fd_set fds;
    
      FD_ZERO(&fds);
      FD_SET(Socket, &fds);
    
      // Set timeout
      SendTimeout.tv_sec  = 0;
      SendTimeout.tv_usec = 250000;              // 250 ms
    
      // As long as we need to send bytes...
      while(iStillToSend > 0)
      {
        iRC = select(0, NULL, &fds, NULL, &SendTimeout);
    
        // Timeout
        if(!iRC)
          return -1;
    
        // Error
        if(iRC < 0)
          return WSAGetLastError();
    
        // Send some bytes
        iSendStatus = send(Socket, pBuffer, iStillToSend, 0);   // Socket is of type
                                                                // 'SOCKET' and is
                                                                // the current
                                                                // connection socket
    
        // Error
        if(iSendStatus < 0)
          return WSAGetLastError();
        else
        {
          // Update buffer and counter
          iStillToSend -= iSendStatus;
          pBuffer += iSendStatus;
        }
      }
    
      return 0;
    }
    This function FD_SET(Socket, &fds) should be used inside the while(iStillToSend > 0) before calling select.

    If you don't do this the select will succeed the first time but then fail even if iStillToSend > 0 (excluding other possible reasons for failure)

    Edit: I am not sure if FD_ZERO should also be inside the while....
    Last edited by miteshpandey; January 21st, 2006 at 11:48 AM.
    If there is no love sun won't shine

  15. #15
    Join Date
    Jan 2006
    Posts
    47

    Re: Winsock help needed NOW!

    Quote Originally Posted by Guidosoft
    OK, so I am only listening for 1 connections at a time. Now, after I accept,, how do I go back to listening on that port using the same listening socket? Hmm?
    The socket you specify in the listen() function will still listen for new incoming connection after a connection has been accepted with the accept() function. The socket descriptor returned by accept() is the socket connected to the client, while the socket descriptor passed as an argument in accept() is unaffected and will still be listening.

    The backlog parameter of the listen() function determines the maximum number of connections that can be queued on the listening socket (ie. connections you haven't accepted) before it sends back WSAECONNREFUSED to the client trying to connect.
    Last edited by runesvend; January 21st, 2006 at 07:55 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured