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
00036
00037
00038
00039
00040
00041 #include "cxutils/networking/socket.h"
00042 #include <string.h>
00043
00044 #ifdef WIN32
00045 #else
00046 #include <stdio.h>
00047 #include <sys/ioctl.h>
00048 #include <sys/socket.h>
00049 #include <net/if.h>
00050 #include <netinet/in.h>
00051 #include <arpa/inet.h>
00052 #endif
00053
00054 using namespace CxUtils;
00055
00056 #ifdef WIN32
00057 unsigned int Socket::mWinsockInitCount = 0;
00058 #endif
00059
00060
00067 Socket::Socket()
00068 {
00069 mSocket = 0;
00070 mNetworkInterface = -1;
00071 mSocketType = Undefined;
00072 mServiceLength = 0;
00073 memset(&mService, 0, sizeof(struct sockaddr_in));
00074 mGoodSocket = false;
00075
00076 #ifdef WIN32
00077
00078
00079 if(mWinsockInitCount == 0)
00080 {
00081 WSADATA wsaData;
00082
00083 WSAStartup(MAKEWORD(2,2), &wsaData);
00084
00085
00086 mWinsockInitCount++;
00087 }
00088 else
00089 {
00090 mWinsockInitCount++;
00091 }
00092 #endif
00093 }
00094
00095
00102 Socket::Socket(const Socket& arg)
00103 {
00104 mSocket = 0;
00105 mNetworkInterface = -1;
00106 mSocketType = Undefined;
00107 mServiceLength = 0;
00108 memset(&mService, 0, sizeof(struct sockaddr_in));
00109 mGoodSocket = false;
00110
00111 #ifdef WIN32
00112
00113
00114 if(mWinsockInitCount == 0)
00115 {
00116 WSADATA wsaData;
00117
00118 WSAStartup(MAKEWORD(2,2), &wsaData);
00119
00120
00121 mWinsockInitCount++;
00122 }
00123 else
00124 {
00125 mWinsockInitCount++;
00126 }
00127 #endif
00128
00129 *this = arg;
00130 }
00131
00132
00138 Socket::~Socket()
00139 {
00140 Shutdown();
00141 #ifdef WIN32
00142 mWinsockInitCount--;
00143 if(mWinsockInitCount == 0)
00144 {
00145
00146
00147
00148 WSACleanup();
00149 }
00150 #endif
00151 }
00152
00153
00159 void Socket::Shutdown()
00160 {
00161
00162 #ifdef WIN32
00163 shutdown(mSocket, 1);
00164 closesocket(mSocket);
00165 #else
00166 if(mSocket > 0)
00167 {
00168 if(shutdown(mSocket, 1) == 0)
00169 {
00170 mSocket = 0;
00171 }
00172 }
00173 if(mSocket > 0)
00174 {
00175 close(mSocket);
00176 }
00177 #endif
00178 mSocket = 0;
00179 mServiceLength = 0;
00180 memset(&mService, 0, sizeof(struct sockaddr_in));
00181 this->mGoodSocket = false;
00182 }
00183
00184
00194 int Socket::Send(const Packet &packet) const
00195 {
00196 return SendFromBuffer(((const char *)(packet.Ptr())), packet.Size());
00197 }
00198
00199
00210 int Socket::Send(const char* buffer, const unsigned int length) const
00211 {
00212 return SendFromBuffer(buffer, length);
00213 }
00214
00215
00232 int Socket::Recv(Packet &packet,
00233 const unsigned int receiveSize,
00234 const long int timeOutMilliseconds,
00235 IPAddress* ipAddress,
00236 unsigned short* port) const
00237 {
00238 int results = 0;
00239 packet.Clear(false);
00240 packet.Reserve(receiveSize);
00241 if( (results = RecvToBuffer((char *)(packet.Ptr()),
00242 receiveSize,
00243 timeOutMilliseconds,
00244 ipAddress,
00245 port)) > 0)
00246 {
00247 packet.SetLength((unsigned int)results);
00248 packet.SetWritePos(0);
00249 packet.SetReadPos(0);
00250 return results;
00251 }
00252 return results;
00253 }
00254
00255
00272 int Socket::Recv(char* buffer, const unsigned int length,
00273 const long int timeOutMilliseconds,
00274 IPAddress* ipAddress,
00275 unsigned short* port) const
00276 {
00277 return RecvToBuffer(buffer, length, timeOutMilliseconds, ipAddress, port);
00278 }
00279
00280
00286 bool Socket::IsValid() const
00287 {
00288 return mGoodSocket;
00289 }
00290
00291
00303 bool Socket::SetNetworkInterface(const int num)
00304 {
00305 mNetworkInterface = num;
00306 return true;
00307 }
00308
00309
00320 bool Socket::SetNetworkInterface(const IP4Address& ipAddress)
00321 {
00322 int num = GetNetworkInterface(ipAddress);
00323 if(num >= 0)
00324 {
00325 return SetNetworkInterface(num);
00326 }
00327 return false;
00328 }
00329
00330
00342 int Socket::GetNetworkInterface(const IP4Address& ipAddress)
00343 {
00344 IP4Address::List hostnames;
00345 if(GetHostAddresses(hostnames))
00346 {
00347 IP4Address::List::iterator host;
00348 int num = 0;
00349 for(host = hostnames.begin(); host != hostnames.end(); host++)
00350 {
00351 if(*host == ipAddress)
00352 {
00353 return num;
00354 }
00355 num++;
00356 }
00357 }
00358
00359 return -1;
00360 }
00361
00362
00368 int Socket::GetSocket() const
00369 {
00370 #ifdef WIN32
00371 return (int)mSocket;
00372 #else
00373 return mSocket;
00374 #endif
00375 }
00376
00389 Socket::Type Socket::GetType() const
00390 {
00391 return mSocketType;
00392 }
00393
00394
00402 int Socket::GetNetworkInterface() const { return mNetworkInterface; }
00403
00404
00415 unsigned int Socket::GetHostAddresses(IP4Address::List& ipAddresses)
00416 {
00417 ipAddresses.clear();
00418
00419 #ifdef WIN32
00420 bool result = false;
00421 char ac[512];
00422 if(Socket::mWinsockInitCount == 0)
00423 {
00424 Socket::InitializeSockets();
00425 }
00426 memset(ac, 0, 512);
00427 if(gethostname(ac, 512) == 0)
00428 {
00429 struct hostent *phe = gethostbyname(ac);
00430 if(phe != 0)
00431 {
00432 struct in_addr addr;
00433 for(int i = 0; phe->h_addr_list[i] != 0; i++)
00434 {
00435 memcpy(&addr, phe->h_addr_list[i], sizeof(struct in_addr));
00436 ipAddresses.push_back( IP4Address(std::string(inet_ntoa(addr))));
00437 }
00438 }
00439 }
00440 #else
00441 struct ifreq buffer[32];
00442 struct ifconf intfc;
00443 struct ifreq *pIntfc;
00444 int i, fd, num_intfc;
00445
00446 intfc.ifc_len = sizeof(buffer);
00447 intfc.ifc_buf = (char*) buffer;
00448
00449 if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
00450 {
00451 perror("socket() failed");
00452 return false;
00453 }
00454
00455 if (ioctl(fd, SIOCGIFCONF, &intfc) < 0)
00456 {
00457 perror("ioctl SIOCGIFCONF failed");
00458 return false;
00459 }
00460
00461 pIntfc = intfc.ifc_req;
00462 num_intfc = intfc.ifc_len / sizeof(struct ifreq);
00463
00464 for (i = 0; i < num_intfc; i++)
00465 {
00466 struct ifreq *item = &(pIntfc[i]);
00467 ipAddresses.push_back( IP4Address(std::string(inet_ntoa(((struct sockaddr_in *)&item->ifr_addr)->sin_addr))) );
00468 }
00469 close(fd);
00470 #endif
00471
00472 return (unsigned int)ipAddresses.size();
00473 }
00474
00475
00484 unsigned int Socket::GetNumNetworkConnections()
00485 {
00486 IP4Address::List ipAddresses;
00487 return GetHostAddresses(ipAddresses);
00488 }
00489
00490
00501 bool Socket::IsHostAddress(const IP4Address& ipAddress)
00502 {
00503 IP4Address::List ipAddresses;
00504 if(ipAddress.mData[0] == 127 && ipAddress.mData[1] == 0 && ipAddress.mData[2] == 0)
00505 {
00506 return true;
00507 }
00508 if(GetHostAddresses(ipAddresses))
00509 {
00510 for(unsigned int i = 0; i < (unsigned int)ipAddresses.size(); i++)
00511 {
00512 if(ipAddresses[i] == ipAddress)
00513 {
00514 return true;
00515 }
00516 }
00517 }
00518 return false;
00519 }
00520
00521
00533 int Socket::IsIncommingData(const Socket *sock, const long int tms)
00534 {
00535 if(!sock || !sock->mGoodSocket)
00536 return 0;
00537
00538 if(tms == 0)
00539 return 1;
00540
00541 #ifdef WIN32
00542 fd_set fds;
00543 timeval tval;
00544
00545
00546 tval.tv_sec = 0;
00547 tval.tv_usec = tms*1000;
00548
00549 fds.fd_array[0] = ((SOCKET)(sock->mSocket));
00550 fds.fd_count = 1;
00551
00552 ::select(0, &fds, NULL, NULL, &tval);
00553 if(fds.fd_count != 1)
00554 return 0;
00555
00556 return 1;
00557 #else
00558 fd_set fds;
00559 int s;
00560 timeval tval;
00561 s = sock->mSocket;
00562
00563 FD_ZERO(&fds);
00564 FD_SET(s, &fds);
00565
00566
00567 tval.tv_sec = 0;
00568 tval.tv_usec = tms*1000;
00569
00570 select(s + 1, &fds, (fd_set *)0, (fd_set *)0,
00571 (struct timeval *)&tval);
00572 if(FD_ISSET(s, &fds) != 0)
00573 return 1;
00574
00575 return 0;
00576 #endif
00577
00578 }
00579
00580
00586 Socket &Socket::operator = (const Socket &arg)
00587 {
00588 this->mSocket = arg.mSocket;
00589 this->mServiceLength = arg.mServiceLength;
00590 this->mSocketType = arg.mSocketType;
00591 memcpy(&this->mService, &arg.mService, sizeof(struct sockaddr_in));
00592
00593 return *this;
00594 }
00595
00596
00602 void Socket::InitializeSockets()
00603 {
00604 #ifdef WIN32
00605
00606
00607 if(mWinsockInitCount == 0)
00608 {
00609 WSADATA wsaData;
00610
00611 WSAStartup(MAKEWORD(2,2), &wsaData);
00612
00613
00614 mWinsockInitCount++;
00615 }
00616 else
00617 {
00618 mWinsockInitCount++;
00619 }
00620 #endif
00621 }
00622
00623
00624