Created
September 21, 2012 15:05
-
-
Save yifu/3762040 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <errno.h> | |
| #include <fcntl.h> | |
| #include <stdio.h> /* for printf() and fprintf() */ | |
| #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */ | |
| #include <arpa/inet.h> /* for sockaddr_in and inet_addr() */ | |
| #include <stdlib.h> /* for atoi() and exit() */ | |
| #include <string.h> /* for memset() */ | |
| #include <unistd.h> /* for close() */ | |
| #define RCVBUFSIZE 32 /* Size of receive buffer */ | |
| void DieWithError(char *errorMessage); /* Error handling function */ | |
| int main(int argc, char *argv[]) | |
| { | |
| int sock; /* Socket descriptor */ | |
| struct sockaddr_in echoServAddr; /* Echo server address */ | |
| unsigned short echoServPort; /* Echo server port */ | |
| char *servIP; /* Server IP address (dotted quad) */ | |
| char *echoString; /* String to send to echo server */ | |
| char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */ | |
| unsigned int echoStringLen; /* Length of string to echo */ | |
| int bytesRcvd, totalBytesRcvd; /* Bytes read in single recv() | |
| and total bytes read */ | |
| if ((argc < 3) || (argc > 4)) /* Test for correct number of arguments */ | |
| { | |
| fprintf(stderr, "Usage: %s <Server IP> <Echo Word> [<Echo Port>]\n", | |
| argv[0]); | |
| exit(1); | |
| } | |
| servIP = argv[1]; /* First arg: server IP address (dotted quad) */ | |
| //echoString = argv[2]; /* Second arg: string to echo */ | |
| echoString = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; /* Second arg: string to echo */ | |
| if (argc == 4) | |
| echoServPort = atoi(argv[3]); /* Use given port, if any */ | |
| else | |
| echoServPort = 7; /* 7 is the well-known port for the echo service */ | |
| /* Create a reliable, stream socket using TCP */ | |
| if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) | |
| DieWithError("socket() 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 */ | |
| /* 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 */ | |
| // NON BLOCKING! | |
| int flags = fcntl (sock, F_GETFL, 0 ); | |
| fcntl (sock, F_SETFL, flags | O_NONBLOCK ); | |
| /* Send the string to the server. */ | |
| int sent = 0; | |
| do | |
| { | |
| std::cout << "Send?" << std::endl; | |
| if ((sent = send(sock, echoString, echoStringLen, 0)) == -1) | |
| { | |
| const int errNumber = errno; | |
| if (errNumber == EWOULDBLOCK || errNumber == EAGAIN) | |
| { | |
| std::cout << "First slow consuming here: [" << sent << "]" << std::endl; | |
| break; | |
| } | |
| } | |
| std::cout << "Sent! [" << sent << "]." << std::endl; | |
| } | |
| while (true); | |
| // SELECT | |
| int servSock[1]; /* Socket descriptors for server */ | |
| servSock[0] = sock; | |
| int maxDescriptor = echoServPort; /* Maximum socket descriptor value */ | |
| fd_set sockSet; /* Set of socket descriptors for select() */ | |
| long timeout = 1; /* Timeout value given on command-line */ | |
| struct timeval selTimeout; /* Timeout for select() */ | |
| int running = 1; /* 1 if server should be running; 0 otherwise */ | |
| int noPorts = 1; /* Number of port specified on command-line */ | |
| int port; /* Looping variable for ports */ | |
| unsigned short portNo; /* Actual port number */ | |
| while (running) | |
| { | |
| /* Zero socket descriptor vector and set for server sockets */ | |
| /* This must be reset every time select() is called */ | |
| FD_ZERO(&sockSet); | |
| /* Add socket to descriptor vector */ | |
| FD_SET(sock, &sockSet); | |
| /* Timeout specification */ | |
| /* This must be reset every time select() is called */ | |
| selTimeout.tv_sec = timeout; /* timeout (secs.) */ | |
| selTimeout.tv_usec = 0; /* 0 microseconds */ | |
| /* Suspend program until descriptor is ready or timeout */ | |
| if (select(maxDescriptor + 1, NULL, &sockSet, NULL, &selTimeout) == 0) | |
| printf("No echo requests for %ld secs...Server still alive\n", timeout); | |
| else | |
| { | |
| if (FD_ISSET(sock, &sockSet)) /* Ready for write !!*/ | |
| { | |
| printf("Ready for write!!!!!! \n"); | |
| // running = 0; | |
| if ((sent = send(sock, echoString, echoStringLen, 0)) == -1) | |
| { | |
| const int errNumber = errno; | |
| if (errNumber == EWOULDBLOCK || errNumber == EAGAIN) | |
| { | |
| std::cout << "Slow consuming here: [" << sent << "]" << std::endl; | |
| } | |
| } | |
| else | |
| { | |
| std::cout << "Sent! [" << sent << "]." << std::endl; | |
| } | |
| } | |
| } | |
| } | |
| printf("\n"); /* Print a final linefeed */ | |
| close(sock); | |
| exit(0); | |
| } | |
| void DieWithError(char *errorMessage) | |
| { | |
| perror(errorMessage); | |
| exit(1); | |
| } | |
| int AcceptTCPConnection(int servSock) | |
| { | |
| int clntSock; /* Socket descriptor for client */ | |
| struct sockaddr_in echoClntAddr; /* Client address */ | |
| unsigned int clntLen; /* Length of client address data structure */ | |
| /* Set the size of the in-out parameter */ | |
| clntLen = sizeof(echoClntAddr); | |
| /* Wait for a client to connect */ | |
| if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr, | |
| &clntLen)) < 0) | |
| DieWithError("accept() failed"); | |
| /* clntSock is connected to a client! */ | |
| printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr)); | |
| return clntSock; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment