|
MASA-Core
|
00001 /******************************************************************************* 00002 * 00003 * Copyright (c) 2010-2015 Edans Sandes 00004 * 00005 * This file is part of MASA-Core. 00006 * 00007 * MASA-Core is free software: you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation, either version 3 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * MASA-Core is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with MASA-Core. If not, see <http://www.gnu.org/licenses/>. 00019 * 00020 ******************************************************************************/ 00021 00022 #include "SocketCellsReader.hpp" 00023 00024 #include <stdio.h> 00025 #include <string.h> 00026 #include <unistd.h> 00027 #include <stdlib.h> 00028 #include <sys/socket.h> /* for socket(), bind(), and connect() */ 00029 #include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */ 00030 #include <errno.h> 00031 #include <netdb.h> //hostent 00032 00033 SocketCellsReader::SocketCellsReader(string hostname, int port) { 00034 this->hostname = hostname; 00035 this->port = port; 00036 this->socketfd = -1; 00037 init(); 00038 } 00039 00040 SocketCellsReader::~SocketCellsReader() { 00041 close(); 00042 } 00043 00044 void SocketCellsReader::close() { 00045 fprintf(stderr, "SocketCellsReader::close(): %d\n", socketfd); 00046 if (socketfd != -1) { 00047 ::close(socketfd); 00048 socketfd = -1; 00049 } 00050 } 00051 00052 int SocketCellsReader::getType() { 00053 return INIT_WITH_CUSTOM_DATA; 00054 } 00055 00056 int SocketCellsReader::read(cell_t* buf, int len) { 00057 int pos = 0; 00058 while (pos < len*sizeof(cell_t)) { 00059 int ret = recv(socketfd, (void*)(((unsigned char*)buf)+pos), len*sizeof(cell_t), 0); 00060 if (ret == -1) { 00061 close(); 00062 fprintf(stderr, "recv: Socket error -1\n"); 00063 break; 00064 } 00065 pos += ret; 00066 } 00067 return pos/sizeof(cell_t); 00068 } 00069 00070 void SocketCellsReader::init() { 00071 int rc; 00072 int sock; /* Socket descriptor */ 00073 struct sockaddr_in echoServAddr; /* Echo server address */ 00074 00075 00076 00077 /* Create a reliable, stream socket using TCP */ 00078 if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { 00079 fprintf(stderr, "ERROR creating socket: %s\n", strerror(errno)); 00080 sleep(1); 00081 } 00082 00083 /* Resolving DNS */ 00084 char ip[100]; 00085 if (resolveDNS(hostname.c_str(), ip)) { 00086 fprintf(stderr, "FATAL: cannot resolve hostname: %s\n", hostname.c_str()); 00087 exit(-1); 00088 } 00089 00090 /* Construct the server address structure */ 00091 memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */ 00092 echoServAddr.sin_family = AF_INET; /* Internet address family */ 00093 echoServAddr.sin_addr.s_addr = inet_addr(ip); /* Server IP address */ 00094 echoServAddr.sin_port = htons(port); /* Server port */ 00095 00096 /* Establish the connection to the echo server */ 00097 int max_retries = 3000; 00098 int retries = 0; 00099 int ok = 0; 00100 fprintf(stderr, "Listening on %s %d\n", hostname.c_str(), port); 00101 while ((retries < max_retries) && !ok) { 00102 if ((rc=connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr))) < 0) { 00103 if (retries % 100 == 0) { 00104 fprintf(stderr, "ERROR connecting to Server %s:%d [Retry %d/%d]. %s\n", ip, port, 00105 retries, max_retries, strerror(errno)); 00106 } 00107 retries++; 00108 usleep(10000); 00109 } else { 00110 ok = 1; 00111 } 00112 } 00113 if (!ok) { 00114 fprintf(stderr, "ERROR connecting to Server. Aborting\n"); 00115 exit(-1); 00116 } 00117 fprintf(stderr, "Connected to Server %s\n", inet_ntoa(echoServAddr.sin_addr)); 00118 00119 this->socketfd = sock; 00120 } 00121 00122 int SocketCellsReader::resolveDNS(const char * hostname , char* ip) { 00123 struct hostent *he; 00124 struct in_addr **addr_list; 00125 int i; 00126 00127 if ( (he = gethostbyname( hostname ) ) == NULL) 00128 { 00129 // get the host info 00130 herror("gethostbyname"); 00131 return 1; 00132 } 00133 00134 addr_list = (struct in_addr **) he->h_addr_list; 00135 00136 for(i = 0; addr_list[i] != NULL; i++) 00137 { 00138 //Return the first one; 00139 strcpy(ip , inet_ntoa(*addr_list[i]) ); 00140 return 0; 00141 } 00142 00143 return 1; 00144 }
1.7.6.1