Advertisement

winsock select() help

Started by November 16, 2005 09:21 PM
1 comment, last by nprz 19 years, 3 months ago
anyone know why my select function doesnt block off correctly it is supposed to recieve only when there is data waiting to be read. if(select(m_socket,&socketReadSet,0,0,&tv)==1) { recv( m_socket, recvbuf, 32, 0 ); } and what exactly does the first parameter of select do... i see all types of things go here.




#include <stdio.h>
#include "winsock2.h"

#include <string>
#include <iostream>

using namespace std;

void main() {

    // Initialize Winsock.
    WSADATA wsaData;
    int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
    if ( iResult != NO_ERROR )
        printf("Error at WSAStartup()\n");

    // Create a socket.
    SOCKET m_socket;
    m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
	//m_socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );

    if ( m_socket == INVALID_SOCKET ) {
        printf( "Error at socket(): %ld\n", WSAGetLastError() );
        WSACleanup();
        return;
    }

    // Bind the socket.
    sockaddr_in service;

    service.sin_family = AF_INET;
    //service.sin_addr.s_addr = inet_addr( "127.0.0.1" );
    service.sin_port = htons( 27015 );

	service.sin_addr.s_addr = inet_addr( "0.0.0.0" );

    if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
        printf( "bind() failed.\n" );
        closesocket(m_socket);
        return;
    }
    
    // Listen on the socket.
    if ( listen( m_socket, 1 ) == SOCKET_ERROR )
        printf( "Error listening on socket.\n");

    // Accept connections.
    SOCKET AcceptSocket;

	char *a1;
	a1 = inet_ntoa(service.sin_addr);
	cout <<"your ip is: " << a1 << endl;

	char a2[100];
	gethostname(a2,100);
	cout <<"your hostname is: " << a2 << endl;

    printf( "Waiting for a client to connect...\n" );
    while (1) {
        AcceptSocket = SOCKET_ERROR;
        while ( AcceptSocket == SOCKET_ERROR ) {
            AcceptSocket = accept( m_socket, NULL, NULL );
        }
        printf( "Client Connected.\n");
        m_socket = AcceptSocket; 
        break;
    }
    
    // Send and receive data.
    int bytesSent;
    int bytesRecv = SOCKET_ERROR;
    char sendbuf[32] = "Server: Sending Data.";
    char recvbuf[32] = "Default recv";
    /*
    bytesRecv = recv( m_socket, recvbuf, 32, 0 );
    printf( "Bytes Recv: %ld\n", bytesRecv );
    
    bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );
    printf( "Bytes Sent: %ld\n", bytesSent );*/


	//string input="null";
	//char input[1];//='$';
	int a =0;

	//int sd =0;
	struct timeval tv;

	tv.tv_sec  = 0;
    tv.tv_usec = 0;

	fd_set socketReadSet;
	FD_ZERO(&socketReadSet);
	FD_SET(m_socket,&socketReadSet);

	//socketReadSet.fd_array[0]=m_socket;

	while(a==0)
	{
		cout << select(m_socket,&socketReadSet,0,0,&tv) << endl;

		if(select(m_socket,&socketReadSet,0,0,&tv)==1)
		{
		recv( m_socket, recvbuf, 32, 0 );
		}
		
		for(int b=0;b<strlen(recvbuf);b++)
		cout << recvbuf;

		cout << endl;

		/*
		recv( m_socket, input, 1, 0 );
		cout << input[0];

		cout << endl;
		*/
	}

    return;
}





or does anyone know how to make m_socket non blocking? i tried: fcntl(m_socket, F_SETFL, O_NONBLOCK); i got this from beej's FAQ but i think that fcntl is unix and im doing win32 [Edited by - jchmack on November 16, 2005 10:23:38 PM]
You can make your socket nonblocking like this:
ioctlsocket(socket,FIONBIO,&mode);


where mode should be an unsigned long with the value 0
Advertisement
Quote:
Original post by jchmack
anyone know why my select function doesnt block off correctly it is supposed to recieve only when there is data waiting to be read.

if(select(m_socket,&socketReadSet,0,0,&tv)==1)
{
recv( m_socket, recvbuf, 32, 0 );
}

and what exactly does the first parameter of select do... i see all types of things go here.



Looking at Beej's tutorial, the first parameter of select is supposed to be the highest file descriptor plus one. Which would be m_socket+1 in your case.

Looking at your source code, even if no data has arrived, you still execute
for(int b=0;b<strlen(recvbuf);b++)
cout << recvbuf;

which would be old data or possibly uninitialized data, be careful about that. You should put int in the if(select) { } area. Also the recv function returns how many bytes were read. This is important to determine if the connection has been closed or if less than 32 bytes were read.

This topic is closed to new replies.

Advertisement