![]() |
| | #1 |
| Registered User Join Date: Feb 2010
Posts: 4
| nonblocking sockets C 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);
}
Last edited by Russian; 02-08-2010 at 12:26 PM. |
| Russian is offline | |
| | #2 |
| Registered User Join Date: Feb 2010
Posts: 4
| problem solved. Moderators can delete the topic |
| Russian is offline | |
| | #3 |
| and the hat of Jobseeking 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? |
| Salem is offline | |
| | #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 | |
| | #6 |
| and the hat of Jobseeking 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. |
| Salem is offline | |
| | #7 |
| Registered User Join Date: Dec 2009 Location: Henderson, NV
Posts: 530
| Thats why I reset the buffer between runs with a memset().... |
| jeffcobb is offline | |
| | #8 |
| and the hat of Jobseeking 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'; 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. |
| Salem is offline | |
| | #9 | |
| Registered User Join Date: Dec 2009 Location: Henderson, NV
Posts: 530
| Quote:
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. | |
| jeffcobb is offline | |
| | #10 | |
| Registered User Join Date: Feb 2010
Posts: 4
| Quote:
you can see last ver at nonblocking sockets C at sources.ru | |
| Russian is offline | |
| | #11 |
| and the hat of Jobseeking 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) ); |
| Salem is offline | |
| | #12 | |
| Registered User Join Date: Dec 2009 Location: Henderson, NV
Posts: 530
| Quote:
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. | |
| jeffcobb is offline | |
![]() |
| Thread Tools | |
| Display Modes | |
|
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 |