|
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 "SocketBuffer.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 00032 SocketBuffer::SocketBuffer(string hostname, int port) { 00033 this->hostname = hostname; 00034 this->port = port; 00035 this->socketfd = -1; 00036 } 00037 00038 00039 SocketBuffer::~SocketBuffer() { 00040 if (socketfd != -1) { 00041 fprintf(stderr, "Buffer::destroy()...\n"); 00042 Buffer::destroy(); 00043 fprintf(stderr, "Close Socket...\n"); 00044 //close(socketfd); 00045 //Buffer::joinThreads(); 00046 } 00047 } 00048 00049 void SocketBuffer::autoFlushThread() { 00050 char data[512]; 00051 00052 int pos = 0; 00053 while (!isDestroyed()) { 00054 int len = readBuffer(data, 1, sizeof(data)); 00055 pos += len; 00056 int ret = send(socketfd, data, len, 0); 00057 if (ret == -1) { 00058 fprintf(stderr, "send: Socket error: -1\n"); 00059 break; 00060 } 00061 if (ret != len) { 00062 fprintf(stderr, "Socket error: Sanity Check. Only %d bytes sent (< %d)\n", ret, len); 00063 break; 00064 } 00065 00066 } 00067 ::close(socketfd); 00068 socketfd = -1; 00069 fprintf(stderr, "End of flush data: %d bytes\n", pos); 00070 } 00071 00072 void SocketBuffer::autoLoadThread() { 00073 char data[512]; 00074 int pos = 0; 00075 while (!isDestroyed()) { 00076 int len = recv(socketfd, data, sizeof(data), 0); 00077 fprintf(stderr, "recv(): %d\n", len); 00078 if (len == -1) { 00079 fprintf(stderr, "recv: Socket error -1\n"); 00080 break; 00081 } 00082 if (len == 0) { 00083 break; 00084 } 00085 pos += len; 00086 writeBuffer(data, 1, len); 00087 } 00088 ::close(socketfd); 00089 socketfd = -1; 00090 fprintf(stderr, "Socket closed by peer: %d bytes\n", pos); 00091 } 00092 00093 void SocketBuffer::initAutoLoad() { 00094 int rc; 00095 int sock; /* Socket descriptor */ 00096 struct sockaddr_in echoServAddr; /* Echo server address */ 00097 00098 00099 00100 /* Create a reliable, stream socket using TCP */ 00101 if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { 00102 fprintf(stderr, "ERROR creating socket: %s\n", strerror(errno)); 00103 sleep(1); 00104 } 00105 00106 /* Construct the server address structure */ 00107 memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */ 00108 echoServAddr.sin_family = AF_INET; /* Internet address family */ 00109 echoServAddr.sin_addr.s_addr = inet_addr(hostname.c_str()); /* Server IP address */ 00110 echoServAddr.sin_port = htons(port); /* Server port */ 00111 00112 /* Establish the connection to the echo server */ 00113 int max_retries = 10; 00114 int retries = 0; 00115 int ok = 0; 00116 while ((retries < max_retries) && !ok) { 00117 if ((rc=connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr))) < 0) { 00118 retries++; 00119 fprintf(stderr, "ERROR connecting to Server [Retry %d/%d]. %s\n", 00120 retries, max_retries, strerror(errno)); 00121 sleep(1); 00122 } else { 00123 ok = 1; 00124 } 00125 } 00126 if (!ok) { 00127 fprintf(stderr, "ERROR connecting to Server. Aborting\n"); 00128 exit(-1); 00129 } 00130 fprintf(stderr, "Connected to Server %s\n", inet_ntoa(echoServAddr.sin_addr)); 00131 00132 this->socketfd = sock; 00133 } 00134 00135 void SocketBuffer::destroyAutoLoad() { 00136 ::close(socketfd); 00137 } 00138 00139 void SocketBuffer::initAutoFlush() { 00140 int rc; 00141 int servSock; /* Socket descriptor for server */ 00142 int clntSock; /* Socket descriptor for client */ 00143 struct sockaddr_in echoServAddr; /* Local address */ 00144 struct sockaddr_in echoClntAddr; /* Client address */ 00145 unsigned int clntLen; /* Length of client address data structure */ 00146 00147 /* Create socket for incoming connections */ 00148 if ((servSock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { 00149 fprintf(stderr, "ERROR creating server socket; return code from socket() is %d\n", servSock); 00150 exit(-1); 00151 } 00152 00153 int optval = 1; 00154 setsockopt(servSock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); 00155 00156 00157 00158 /* Construct local address structure */ 00159 memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */ 00160 echoServAddr.sin_family = AF_INET; /* Internet address family */ 00161 echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */ 00162 echoServAddr.sin_port = htons(port); /* Local port */ 00163 00164 /* Bind to the local address */ 00165 if ((rc = bind(servSock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr))) < 0) { 00166 fprintf(stderr, "ERROR; return code from bind() is %d\n", rc); 00167 exit(-1); 00168 } 00169 00170 /* Mark the socket so it will listen for incoming connections */ 00171 if ((rc=listen(servSock, 1)) < 0) { 00172 fprintf(stderr, "ERROR; return code from listen() is %d\n", rc); 00173 exit(-1); 00174 } 00175 00176 /* Set the size of the in-out parameter */ 00177 clntLen = sizeof(echoClntAddr); 00178 00179 /* Wait for a client to connect */ 00180 if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr, &clntLen)) < 0){ 00181 fprintf(stderr, "ERROR; return code from accept() is %d\n", clntSock); 00182 exit(-1); 00183 } 00184 00185 /* clntSock is connected to a client! */ 00186 00187 fprintf(stderr, "Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr)); 00188 00189 //HandleTCPClient(clntSock); 00190 00191 ::close(servSock); 00192 00193 this->socketfd = clntSock; 00194 } 00195 00196 void SocketBuffer::destroyAutoFlush() { 00197 00198 }
1.7.6.1