C Board  

Go Back   C Board > General Programming Boards > Networking/Device Communication

Reply
 
LinkBack Thread Tools Display Modes
Old 07-02-2009, 04:11 PM   #1
Registered User
 
Join Date: Mar 2009
Posts: 71
Could someone explain how to use the Select function.

I have done alot of stuff with Winsock, but it's all with sockets that can olni process one at a time.


Can anyone tell me how to make a non-blocking socket? [send and recive]
azjherben is offline   Reply With Quote
Old 07-02-2009, 05:35 PM   #2
int x = *((int *) NULL);
 
Cactus_Hugger's Avatar
 
Join Date: Jul 2003
Location: Banks of the River Styx
Posts: 890
LMGTFY

Depends on OS, really. For most OS, I believe this is it:
Code:
int flags = fcntl(socket_fd, F_GETFL);
fcntl(socket_fd, F_SETFL, flags (add or remove O_NONBLOCK));
If you happen to be on Windows, it does it differently:
Code:
unsigned long what = (0 for blocking, anything else for non-blocking.);
ioctlsocket(your_socket, FIONBIO, &what);
__________________
long time; /* know C? */
Unprecedented performance: Nothing ever ran this slow before.
Any sufficiently advanced bug is indistinguishable from a feature.
Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
The best way to accelerate an IBM is at 9.8 m/s/s.
recursion (re - cur' - zhun) n. 1. (see recursion)
Cactus_Hugger is offline   Reply With Quote
Old 07-02-2009, 06:00 PM   #3
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,357
Quote:
Originally Posted by azjherben View Post
I have done alot of stuff with Winsock, but it's all with sockets that can olni process one at a time.


Can anyone tell me how to make a non-blocking socket? [send and recive]
You use BLOCKING sockets with select(), not non-blocking. The purpose of select is to be able to wait until any one of an entire SET of sockets becomes ready for reading instead of blocking on a single one of them.
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 07-02-2009, 06:28 PM   #4
Registered User
 
Join Date: Mar 2009
Posts: 71
This is one of mi header files.
Tell me if I did it right.


Code:
//Socket.cpp
#include "Socket.h"

Socket::Socket()
{
    if( WSAStartup( MAKEWORD(2, 2), &wsaData ) != NO_ERROR )
    {
        cerr<<"Socket Initialization: Error with WSAStartup\n";
        system("pause");
        WSACleanup();
        exit(10);
    }

    //Create a socket
    
    
    mySocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );

unsigned long what = (4);
ioctlsocket(mySocket, FIONBIO, &what);


    if ( mySocket == INVALID_SOCKET )
    {
        cerr<<"Socket Initialization: Error creating socket"<<endl;
        system("pause");
        WSACleanup();
        exit(11);
    }

    myBackup = mySocket;
}

Socket::~Socket()
{
    WSACleanup();
}

bool Socket::SendData( char *buffer )
{
    send( mySocket, buffer, strlen( buffer ), 0 );
    return true;
}

bool Socket::RecvData( char *buffer, int size )
{
    int i = recv( mySocket, buffer, size, 0 );
    buffer[i] = '\0';
    return true;
}

void Socket::CloseConnection()
{
    //cout<<"CLOSE CONNECTION"<<endl;
    closesocket( mySocket );
    mySocket = myBackup;
}

void Socket::GetAndSendMessage()
{
    char message[STRLEN];
    cin.ignore();//without this, it gets the return char from the last cin and ignores the following one!
    cout<<"Send > ";
    cin.get( message, STRLEN );
    SendData( message );
}

void ServerSocket::StartHosting( int port )
{
     Bind( port );
     Listen();
}

void ServerSocket::Listen()
{
    //cout<<"LISTEN FOR CLIENT..."<<endl;
    
    if ( listen ( mySocket, 1 ) == SOCKET_ERROR )
    {
        cerr<<"ServerSocket: Error listening on socket\n";
        system("pause");
        WSACleanup();
        exit(15);
    }
    
    //cout<<"ACCEPT CONNECTION..."<<endl;
    
    acceptSocket = accept( myBackup, NULL, NULL );
    while ( acceptSocket == SOCKET_ERROR )
    {
        acceptSocket = accept( myBackup, NULL, NULL );
    }
    mySocket = acceptSocket;
}

void ServerSocket::Bind( int port )
{
    myAddress.sin_family = AF_INET;
    myAddress.sin_addr.s_addr = inet_addr( "0.0.0.0" );
    myAddress.sin_port = htons( port );
    
    //cout<<"BIND TO PORT "<<port<<endl;

    if ( bind ( mySocket, (SOCKADDR*) &myAddress, sizeof( myAddress) ) == SOCKET_ERROR )
    {
        cerr<<"ServerSocket: Failed to connect\n";
        system("pause");
        WSACleanup();
        exit(14);
    }
}

void ClientSocket::ConnectToServer( const char *ipAddress, int port )
{
    myAddress.sin_family = AF_INET;
    myAddress.sin_addr.s_addr = inet_addr( ipAddress );
    myAddress.sin_port = htons( port );
    
    //cout<<"CONNECTED"<<endl;

    if ( connect( mySocket, (SOCKADDR*) &myAddress, sizeof( myAddress ) ) == SOCKET_ERROR )
    {
        cerr<<"ClientSocket: Failed to connect\n";
        system("pause");
        WSACleanup();
        exit(13);
    } 
}
azjherben is offline   Reply With Quote
Old 07-03-2009, 12:45 PM   #5
int x = *((int *) NULL);
 
Cactus_Hugger's Avatar
 
Join Date: Jul 2003
Location: Banks of the River Styx
Posts: 890
Quote:
Originally Posted by brewbuck View Post
You use BLOCKING sockets with select(), not non-blocking. The purpose of select is to be able to wait until any one of an entire SET of sockets becomes ready for reading instead of blocking on a single one of them.
Generally, you use non-blocking sockets. Using blocking sockets would provide a disadvantage that you would only be able to perform 1 recv() until you would have to return to a select() call. If more data is available then your initial recv() on the socket, then you'll miss out until you call select() again. If you use non-blocking sockets, however, then you can just recv() until there is no more data.

Furthermore, and more seriously, the man page for select() notes that:
Quote:
Originally Posted by man 2 select
Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block.
As for the OP's code, some notes:
1) You can use INADDR_ANY in place of inet_addr( "0.0.0.0" );
2) If WSAStartup() fails, WSACleanup() is probably unneeded.
3)
Code:
    acceptSocket = accept( myBackup, NULL, NULL );
    while ( acceptSocket == SOCKET_ERROR )
    {
        acceptSocket = accept( myBackup, NULL, NULL );
    }
    mySocket = acceptSocket;
do-while?
4) '4' is an arbitrary number... just because the man page said 'non-zero' doesn't mean you have to follow it that closely. Try something more sane, like... 1? Otherwise, readers are going to be wondering what '4' does.
5) In SendData(), check the return value. send() might not send() everything you ask of it, especially with non-blocking sockets.
5) RecvData has a buffer overflow.
Code:
bool Socket::RecvData( char *buffer, int size )
{
    int i = recv( mySocket, buffer, size, 0 );
    buffer[i] = '\0';
    return true;
}
First, check that return value. If something goes wrong (ie, error, or since it's a non-blocking socket, it signals that it would block) then it will return negative, and you'll have buffer[negative #], which is obviously not a Good Thing™. Furthermore, in the case of extreme success, recv() actually recv's size bytes, it'll return size, and buffer[size] is off by one. (If it's string data though, you do need to terminate that buffer though! recv() size-1, and make sure that recv()'s ret isn't negative!)
__________________
long time; /* know C? */
Unprecedented performance: Nothing ever ran this slow before.
Any sufficiently advanced bug is indistinguishable from a feature.
Real Programmers confuse Halloween and Christmas, because dec 25 == oct 31.
The best way to accelerate an IBM is at 9.8 m/s/s.
recursion (re - cur' - zhun) n. 1. (see recursion)

Last edited by Cactus_Hugger; 07-03-2009 at 12:56 PM.
Cactus_Hugger is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Troubleshooting Input Function SiliconHobo C Programming 14 12-05-2007 07:18 AM
Calling a Thread with a Function Pointer. ScrollMaster Windows Programming 6 06-10-2006 08:56 AM
Bisection Method function value at root incorrect mr_glass C Programming 3 11-10-2005 09:10 AM
Change this program so it uses function?? stormfront C Programming 8 11-01-2005 08:55 AM
Didn't quite know where to post this.......compiler problem... incognito C++ Programming 5 02-08-2003 07:42 PM


All times are GMT -6. The time now is 03:33 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22