00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "../commun/communSocket.h"
00036
00037 CommunSocket::CommunSocket( int connectMode, const String& hostname, unsigned short port) :
00038
00039 _connectMode( connectMode),
00040 _hostname( hostname),
00041 _port( port) {
00042
00043 FD_ZERO( &_fds);
00044
00045 #ifdef WIN32
00046 _csock = INVALID_SOCKET;
00047
00048 WSADATA wsaData;
00049 if( _failed = (WSAStartup( MAKEWORD( 1, 1), &wsaData) != 0)) return;
00050
00051 if( _failed = ((_sock = socket( AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)) return;
00052 #else
00053 _csock = -1;
00054
00055 if( _failed = ((_sock = socket( PF_INET, SOCK_STREAM, 0)) < 0)) return;
00056 #endif
00057
00058 if( _connectMode) {
00059
00060 _csock = _sock;
00061 return;
00062 }
00063
00064 sockaddr_in sin;
00065 sin.sin_family = AF_INET;
00066 sin.sin_port = htons( port);
00067 sin.sin_addr.s_addr = htonl( INADDR_ANY);
00068
00069 #ifdef WIN32
00070 if( _failed = (bind( _sock, (sockaddr*)&sin, sizeof( sin)) == SOCKET_ERROR)) return;
00071 if( _failed = (listen( _sock, 1) == SOCKET_ERROR)) return;
00072 #else
00073 if( _failed = (bind( _sock, (sockaddr*)&sin, sizeof( sin)) < 0)) return;
00074 if( _failed = (listen( _sock, 1) < 0)) return;
00075 #endif
00076 }
00077
00078 CommunSocket::~CommunSocket() {
00079
00080 #ifdef WIN32
00081 if( !_connectMode) {
00082
00083 shutdown( _sock, SD_BOTH);
00084 closesocket( _sock);
00085 }
00086
00087 shutdown( _csock, SD_BOTH);
00088 closesocket( _csock);
00089
00090 WSACleanup();
00091 #else
00092 if( !_connectMode) {
00093
00094 shutdown( _sock, SHUT_RDWR);
00095 close( _sock);
00096 }
00097
00098 shutdown( _csock, SHUT_RDWR);
00099 close( _csock);
00100 #endif
00101 }
00102
00103 int CommunSocket::initialize() {
00104
00105 sockaddr_in cin;
00106
00107 #ifdef WIN32
00108 int csize = sizeof( cin);
00109 #else
00110 socklen_t csize = sizeof( cin);
00111 #endif
00112
00113 if( !_connectMode) {
00114 #ifdef WIN32
00115 if( _csock != INVALID_SOCKET) {
00116
00117 shutdown( _csock, SD_BOTH);
00118 closesocket( _csock);
00119 }
00120
00121 _failed = ((_csock = accept( _sock, (sockaddr*)&cin, &csize)) == INVALID_SOCKET);
00122 #else
00123 if( _csock >= 0) {
00124
00125 shutdown( _csock, SHUT_RDWR);
00126 close( _csock);
00127 }
00128
00129 _failed = ((_csock = accept( _sock, (sockaddr*)&cin, &csize)) < 0);
00130 #endif
00131 }
00132 else {
00133
00134 cin.sin_family = AF_INET;
00135 cin.sin_port = htons( _port);
00136
00137 hostent* h = gethostbyname( _hostname);
00138 if( _failed = (h == NULL)) return 0;
00139
00140 cin.sin_addr.s_addr = *(unsigned long*)h->h_addr_list[0];
00141
00142 #ifdef WIN32
00143 _failed = (connect( _csock, (sockaddr*)&cin, csize) == SOCKET_ERROR);
00144 #else
00145 _failed = (connect( _csock, (sockaddr*)&cin, csize) < 0);
00146 #endif
00147 }
00148
00149 if( !_failed) {
00150
00151 FD_ZERO( &_fds);
00152 FD_SET( _csock, &_fds);
00153 }
00154 else if( _connectMode) {
00155
00156 #ifdef WIN32
00157 shutdown( _csock, SD_BOTH);
00158 closesocket( _csock);
00159
00160 _csock = socket( AF_INET, SOCK_STREAM, 0);
00161 #else
00162 shutdown( _csock, SHUT_RDWR);
00163 close( _csock);
00164
00165 _csock = socket( PF_INET, SOCK_STREAM, 0);
00166 #endif
00167 }
00168
00169 return !_failed;
00170 }
00171
00172 Commun& CommunSocket::operator<<( const Buffer& b) {
00173
00174
00175 jint size = b.getSize();
00176 jint nsize = htonl( size);
00177
00178 #ifdef WIN32
00179 if( _failed = (send( _csock, (char*)&nsize, sizeof( nsize), 0) == SOCKET_ERROR)) return *this;
00180
00181 _failed = (size && send( _csock, b.getBuffer(), size, 0) == SOCKET_ERROR);
00182 #else
00183 if( _failed = (send( _csock, (char*)&nsize, sizeof( nsize), 0) < 0)) return *this;
00184
00185 _failed = (size && send( _csock, b.getBuffer(), size, 0) < 0);
00186 #endif
00187
00188 return *this;
00189 }
00190
00191 Commun& CommunSocket::operator>>( Buffer& b) {
00192
00193 jint nsize;
00194 int rc = recv( _csock, (char*)&nsize, sizeof( nsize), 0);
00195
00196 #ifdef WIN32
00197 if( _failed = (rc == SOCKET_ERROR || rc < sizeof( nsize))) return *this;
00198 #else
00199 if( _failed = (rc < 0 || rc < sizeof( nsize))) return *this;
00200 #endif
00201
00202
00203 jint size = ntohl( nsize);
00204
00205 if( size) {
00206
00207 char* buf = new char[size];
00208
00209 rc = recv( _csock, buf, size, 0);
00210
00211 #ifdef WIN32
00212 _failed = (rc == SOCKET_ERROR || rc < size);
00213 #else
00214 _failed = (rc < 0 || rc < size);
00215 #endif
00216
00217 if( !_failed) b = Buffer( buf, size);
00218
00219 delete[] buf;
00220 }
00221 else b.clear();
00222
00223 return *this;
00224 }
00225
00226 int CommunSocket::isReady() {
00227
00228 int rc = select( _csock+1, &_fds, NULL, NULL, NULL);
00229
00230 #ifdef WIN32
00231 if( rc == SOCKET_ERROR) return !(_failed = 1);
00232 #else
00233 if( rc < 0) return !(_failed = 1);
00234 #endif
00235
00236 return rc;
00237 }