C Board  

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

Reply
 
LinkBack Thread Tools Display Modes
Old 02-08-2010, 08:50 AM   #1
Registered User
 
Join Date: Feb 2010
Posts: 4
nonblocking sockets C

Hello.
Pre forgive me for my English
my program (using non blocking sockets) should connect to server, send string and async recieve replies form server.
but it cant connect to server
Code:
#include <stdio.h>      /* for printf(), fprintf() */
#include <winsock2.h>    /* for socket(),... */
#include <stdlib.h>     /* for exit() */
#include <time.h>
#include <sys/types.h>

#define RCVBUFSIZE 32   /* Size of receive buffer */

void DieWithError(char *errorMessage){
    perror(errorMessage);
    exit(0);
};  /* Error handling function */

void main(int argc, char *argv[])
{
    int sock, rc;                        /* Socket descriptor */
    struct sockaddr_in echoServAddr; /* Echo server address */
    unsigned short echoServPort;     /* Echo server port */
    //char *servIP;                    /* Server IP address (dotted quad) */
    char servIP[] = "10.42.43.1";
	char echoString[]= "identifier=1z2y3z \r\n\r\n";
    char echoBuffer[RCVBUFSIZE];     /* Buffer for echo string */
    int echoStringLen;               /* Length of string to echo */
    int bytesRcvd, totalBytesRcvd;   /* Bytes read in single recv() and total bytes read */
    WSADATA wsaData;                 /* Structure for WinSock setup communication */
    unsigned long nonblocking = 1;
	fd_set writefds, readfds;
	struct timeval tv;
    tv.tv_sec = 5;
    tv.tv_usec = 500000;
    //servIP =  argv[1];             /* First arg: server IP address (dotted quad) */
    echoServPort = 8088; //atoi(8088);  //atoi(argv[2]);  /* Use given port, if any */
    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
    {
        fprintf(stderr, "WSAStartup() failed");
        exit(1);
    }

    /* Create a reliable, stream socket using TCP */
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0)
        DieWithError("socket() failed");
   

    /* Set the socket to nonblocking */
    if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0)
        DieWithError("ioctlsocket() failed");

    /* Construct the server address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
    echoServAddr.sin_family      = AF_INET;             /* Internet address family */
    echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */
    echoServAddr.sin_port        = htons(echoServPort); /* Server port */
    
    FD_ZERO(&writefds);
    FD_SET(sock, &writefds);
	rc = select(sock, NULL, &writefds, NULL, &tv);
	if((rc == 1) && (FD_ISSET(sock, &writefds)))
{
	/* Establish the connection to the echo server */
    if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
		DieWithError("connect() failed");
	}
	
    echoStringLen = strlen(echoString);          /* Determine input length */

	FD_ZERO(&readfds);
    FD_SET(sock, &readfds);
	rc = select(sock, &readfds, NULL, NULL, &tv);
	if((rc == 1) && (FD_ISSET(sock, &readfds)))
    {
    /* Send the string, including the null terminator, to the server */
    if (send(sock, echoString, echoStringLen, 0) != echoStringLen)
        DieWithError("send() sent a different number of bytes than expected");
	}
    /* Receive the same string back from the server */
    totalBytesRcvd = 0;
    printf("Received: ");                /* Setup to print the echoed string */
    while (totalBytesRcvd < echoStringLen)
    {
        /* Receive up to the buffer size (minus 1 to leave space for 
           a null terminator) bytes from the sender */
        if ((bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0)) <= 0)
            DieWithError("recv() failed or connection closed prematurely");
        totalBytesRcvd += bytesRcvd;   /* Keep tally of total bytes */
        echoBuffer[bytesRcvd] = '\0';  /* Add \0 so printf knows where to stop */
        printf("%s", echoBuffer);            /* Print the echo buffer */
    }
	


    printf("\n");    /* Print a final linefeed */

    closesocket(sock);
    WSACleanup();  /* Cleanup Winsock */

    exit(0);
}
select return 0 (timeout)

Last edited by Russian; 02-08-2010 at 12:26 PM.
Russian is offline   Reply With Quote
Old 02-08-2010, 01:15 PM   #2
Registered User
 
Join Date: Feb 2010
Posts: 4
problem solved. Moderators can delete the topic
Russian is offline   Reply With Quote
Old 02-08-2010, 03:15 PM   #3
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,630
Rather than delete it, how about you explain your solution for the benefit of others?
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 02-09-2010, 03:44 AM   #4
Registered User
 
Join Date: Feb 2010
Posts: 4
implementation of the task (async recv and other) i will perform "off one's own bat"
(Google Translate )
Code:
#include <stdio.h>      /* for printf(), fprintf() */
#include <winsock2.h>    /* for socket(),... */
#include <stdlib.h>     /* for exit() */
#include <time.h>
#include <sys/types.h>

#define RCVBUFSIZE 3200   /* Size of receive buffer */

void DieWithError(char *errorMessage){
    perror(errorMessage);
    exit(0);
};  /* Error handling function */

void main(int argc, char *argv[])
{
    int sock, rc;                        /* Socket descriptor */
    struct sockaddr_in echoServAddr; /* Echo server address */
    unsigned short echoServPort;     /* Echo server port */
    //char *servIP;                    /* Server IP address (dotted quad) */
    char servIP[] = "10.42.43.1";
    char echoString[]= "identifier=1z2y3z \r\n\r\n";
    char echoBuffer[RCVBUFSIZE];     /* Buffer for echo string */
    int echoStringLen;               /* Length of string to echo */
    int bytesRcvd, totalBytesRcvd;   /* Bytes read in single recv() and total bytes read */
    WSADATA wsaData;                 /* Structure for WinSock setup communication */
    unsigned long nonblocking = 1;
    fd_set writefds, readfds;
    struct timeval tv;
    tv.tv_sec = 5;
    tv.tv_usec = 500000;
    //servIP =  argv[1];             /* First arg: server IP address (dotted quad) */
    echoServPort = 80; //atoi(8088);  //atoi(argv[2]);  /* Use given port, if any */

    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
    {
        fprintf(stderr, "WSAStartup() failed");
        exit(1);
    }

    /* Create a reliable, stream socket using TCP */
    if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0)
        DieWithError("socket() failed");
   

    /* Set the socket to nonblocking */
    if (ioctlsocket(sock, FIONBIO, &nonblocking) != 0)
        DieWithError("ioctlsocket() failed");

    /* Construct the server address structure */
    memset(&echoServAddr, 0, sizeof(echoServAddr));     /* Zero out structure */
    echoServAddr.sin_family      = AF_INET;             /* Internet address family */
    echoServAddr.sin_addr.s_addr = inet_addr(servIP);   /* Server IP address */
    echoServAddr.sin_port        = htons(echoServPort); /* Server port */

    connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)); 

    FD_ZERO(&writefds);
    FD_SET(sock, &writefds);
    rc = select(sock, NULL, &writefds, NULL, &tv);

    if((rc == 1) && (FD_ISSET(sock, &writefds))) {
        printf("connect success\n");
    } else {
        printf("connect error\n");
    return;
    }

    send(sock, "1234", 4, 0);// send something

    FD_ZERO(&readfds);
    FD_SET(sock, &readfds);
    rc = select(sock, &readfds, NULL, NULL, &tv);

    printf("read\n");


    if((rc == 1) && (FD_ISSET(sock, &readfds))) { // get the answer and display
        bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0);
        printf("received %d bytes\n", bytesRcvd);
        printf("%s\n", echoBuffer);
        } else {
    printf("read error\n");
    return; 
    }

    WSACleanup();  // Cleanup Winsock
}

Last edited by Russian; 02-09-2010 at 03:46 AM.
Russian is offline   Reply With Quote
Old 02-09-2010, 09:01 AM   #5
Registered User
 
jeffcobb's Avatar
 
Join Date: Dec 2009
Location: Henderson, NV
Posts: 530
Ah yes Google Translations; providing translation humor for a generation...
__________________
C/C++ Environment: GNU CC/Emacs
Make system: CMake
Debuggers: Valgrind/GDB
jeffcobb is offline   Reply With Quote
Old 02-09-2010, 12:44 PM   #6
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,630
> printf("%s\n", echoBuffer);
Just "off the bat" as it were, where is the \0 at the end of this array you've recv()'ed ?

Because recv() didn't store one, and neither did you.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 02-09-2010, 12:49 PM   #7
Registered User
 
jeffcobb's Avatar
 
Join Date: Dec 2009
Location: Henderson, NV
Posts: 530
Quote:
Originally Posted by Salem View Post
> printf("%s\n", echoBuffer);
Just "off the bat" as it were, where is the \0 at the end of this array you've recv()'ed ?

Because recv() didn't store one, and neither did you.
Thats why I reset the buffer between runs with a memset()....
__________________
C/C++ Environment: GNU CC/Emacs
Make system: CMake
Debuggers: Valgrind/GDB
jeffcobb is offline   Reply With Quote
Old 02-09-2010, 01:28 PM   #8
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,630
I prefer (after error checking) to do

Code:
bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0);
echoBuffer[bytesRcvd] = '\0';
It's considerably quicker than memset'ing.

Using memset to clear any char array just seems like voodoo programming to me.
Unless there is a nice comment like "cleared to prevent information leaks" or some other good reason.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 02-09-2010, 01:33 PM   #9
Registered User
 
jeffcobb's Avatar
 
Join Date: Dec 2009
Location: Henderson, NV
Posts: 530
Quote:
Originally Posted by Salem View Post
I prefer (after error checking) to do

Code:
bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0);
echoBuffer[bytesRcvd] = '\0';
It's considerably quicker than memset'ing.

Using memset to clear any char array just seems like voodoo programming to me.
Unless there is a nice comment like "cleared to prevent information leaks" or some other good reason.
Not really. There are any number of C lib string methods that will fill a string with some formatted data and not stick on a terminating null. Seek them out to see what I mean...

Here is but one...and the first one is always free

strncpy - C++ Reference

So if that is voodoo programming, well then BOOGA BOOGA! My code works.
__________________
C/C++ Environment: GNU CC/Emacs
Make system: CMake
Debuggers: Valgrind/GDB
jeffcobb is offline   Reply With Quote
Old 02-09-2010, 01:53 PM   #10
Registered User
 
Join Date: Feb 2010
Posts: 4
Quote:
Originally Posted by Salem View Post
I prefer (after error checking) to do

Code:
bytesRcvd = recv(sock, echoBuffer, RCVBUFSIZE - 1, 0);
echoBuffer[bytesRcvd] = '\0';
It's considerably quicker than memset'ing.
in last version of my small socket-based client im using it
you can see last ver at nonblocking sockets C at sources.ru
Russian is offline   Reply With Quote
Old 02-09-2010, 03:47 PM   #11
and the hat of Jobseeking
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,630
> if ( ( bytesRcvd = recv( sock, echoBuffer, MAXDATASIZE, 0 ) ) == SOCKET_ERROR )
So what happens if you make MAXDATASIZE larger than RCVBUFSIZE without realising the implications?

In other words, try
if ( ( bytesRcvd = recv( sock, echoBuffer, sizeof(echoBuffer)-1, 0 ) ) == SOCKET_ERROR )

You also need to check for bytesRcvd == 0 as well.


@jeff
> There are any number of C lib string methods that will fill a string with some formatted data and not stick on a terminating null
Fine, does this have a \0?
Code:
char buff[5];
memset( buff, 0, sizeof(buff) );
strncpy( buff, anotherstring, sizeof(buff) );
?
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.

Salem is offline   Reply With Quote
Old 02-09-2010, 06:28 PM   #12
Registered User
 
jeffcobb's Avatar
 
Join Date: Dec 2009
Location: Henderson, NV
Posts: 530
Quote:
Originally Posted by Salem View Post
> if ( ( bytesRcvd = recv( sock, echoBuffer, MAXDATASIZE, 0 ) ) == SOCKET_ERROR )
So what happens if you make MAXDATASIZE larger than RCVBUFSIZE without realising the implications?

In other words, try
if ( ( bytesRcvd = recv( sock, echoBuffer, sizeof(echoBuffer)-1, 0 ) ) == SOCKET_ERROR )

You also need to check for bytesRcvd == 0 as well.


@jeff
> There are any number of C lib string methods that will fill a string with some formatted data and not stick on a terminating null
Fine, does this have a \0?
Code:
char buff[5];
memset( buff, 0, sizeof(buff) );
strncpy( buff, anotherstring, sizeof(buff) );
?
At first glance that would depend on the size of anotherString.

But who the hell codes that way? looks like one of those "sample" code pieces you used to see in the commercial lint tool in Dr. Dobbs...you know you always strncpy to 1 byte less than the size of your buffer...the memset was not a cure-all but to be taken together with common sense and experience.
__________________
C/C++ Environment: GNU CC/Emacs
Make system: CMake
Debuggers: Valgrind/GDB
jeffcobb is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Unix Nonblocking Reads on Sockets winderjj Networking/Device Communication 5 09-10-2008 07:17 AM
Best way to poll sockets? 39ster Networking/Device Communication 3 07-22-2008 01:43 PM
nonblocking sockets - select approach l2u Networking/Device Communication 1 09-26-2006 11:43 AM
Raw Sockets and SP2... Devil Panther Networking/Device Communication 11 08-12-2005 04:52 AM
Starting window sockets _Cl0wn_ Windows Programming 2 01-20-2003 11:49 AM


All times are GMT -6. The time now is 09:54 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.2

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