mirror of
https://github.com/glest/glest-source.git
synced 2025-08-14 04:13:58 +02:00
First Attempt at merging socket code into cross platform classes
This commit is contained in:
@@ -28,11 +28,22 @@
|
|||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
typedef SOCKET PLATFORM_SOCKET;
|
||||||
|
|
||||||
|
const char* WSAGetLastErrorMessage(const char* pcMessagePrefix,int nErrorID = 0);
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef int PLATFORM_SOCKET;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Shared{ namespace Platform{
|
namespace Shared{ namespace Platform{
|
||||||
|
|
||||||
//
|
//
|
||||||
// This interface describes the methods a callback object must implement
|
// This interface describes the methods a callback object must implement
|
||||||
// when signalled with detected servers
|
// when signaled with detected servers
|
||||||
//
|
//
|
||||||
class DiscoveredServersInterface {
|
class DiscoveredServersInterface {
|
||||||
public:
|
public:
|
||||||
@@ -42,7 +53,6 @@ public:
|
|||||||
// =====================================================
|
// =====================================================
|
||||||
// class IP
|
// class IP
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
class Ip {
|
class Ip {
|
||||||
private:
|
private:
|
||||||
unsigned char bytes[4];
|
unsigned char bytes[4];
|
||||||
@@ -61,13 +71,28 @@ public:
|
|||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
class Socket {
|
class Socket {
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
private:
|
||||||
|
class SocketManager{
|
||||||
|
public:
|
||||||
|
SocketManager();
|
||||||
|
~SocketManager();
|
||||||
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int sock;
|
static SocketManager socketManager;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PLATFORM_SOCKET sock;
|
||||||
long lastDebugEvent;
|
long lastDebugEvent;
|
||||||
static int broadcast_portno;
|
static int broadcast_portno;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Socket(int sock);
|
Socket(PLATFORM_SOCKET sock);
|
||||||
Socket();
|
Socket();
|
||||||
virtual ~Socket();
|
virtual ~Socket();
|
||||||
|
|
||||||
@@ -76,12 +101,12 @@ public:
|
|||||||
static std::vector<std::string> getLocalIPAddressList();
|
static std::vector<std::string> getLocalIPAddressList();
|
||||||
|
|
||||||
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
||||||
static bool hasDataToRead(std::map<int,bool> &socketTriggeredList);
|
static bool hasDataToRead(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList);
|
||||||
static bool hasDataToRead(int socket);
|
static bool hasDataToRead(PLATFORM_SOCKET socket);
|
||||||
bool hasDataToRead();
|
bool hasDataToRead();
|
||||||
void disconnectSocket();
|
void disconnectSocket();
|
||||||
|
|
||||||
int getSocketId() const { return sock; }
|
PLATFORM_SOCKET getSocketId() const { return sock; }
|
||||||
|
|
||||||
int getDataToRead();
|
int getDataToRead();
|
||||||
int send(const void *data, int dataSize);
|
int send(const void *data, int dataSize);
|
||||||
@@ -89,7 +114,7 @@ public:
|
|||||||
int peek(void *data, int dataSize);
|
int peek(void *data, int dataSize);
|
||||||
|
|
||||||
void setBlock(bool block);
|
void setBlock(bool block);
|
||||||
static void setBlock(bool block, int socket);
|
static void setBlock(bool block, PLATFORM_SOCKET socket);
|
||||||
|
|
||||||
bool isReadable();
|
bool isReadable();
|
||||||
bool isWritable(bool waitOnDelayedResponse);
|
bool isWritable(bool waitOnDelayedResponse);
|
||||||
@@ -97,9 +122,10 @@ public:
|
|||||||
|
|
||||||
static string getHostName();
|
static string getHostName();
|
||||||
static string getIp();
|
static string getIp();
|
||||||
|
bool isSocketValid(PLATFORM_SOCKET *validateSocket=NULL) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void throwException(const string &str);
|
static void throwException(string str);
|
||||||
};
|
};
|
||||||
|
|
||||||
class BroadCastClientSocketThread : public Thread
|
class BroadCastClientSocketThread : public Thread
|
||||||
@@ -127,7 +153,6 @@ public:
|
|||||||
// =====================================================
|
// =====================================================
|
||||||
// class ClientSocket
|
// class ClientSocket
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
class ClientSocket: public Socket {
|
class ClientSocket: public Socket {
|
||||||
public:
|
public:
|
||||||
ClientSocket();
|
ClientSocket();
|
||||||
@@ -167,7 +192,6 @@ public:
|
|||||||
// =====================================================
|
// =====================================================
|
||||||
// class ServerSocket
|
// class ServerSocket
|
||||||
// =====================================================
|
// =====================================================
|
||||||
|
|
||||||
class ServerSocket: public Socket{
|
class ServerSocket: public Socket{
|
||||||
public:
|
public:
|
||||||
ServerSocket();
|
ServerSocket();
|
||||||
|
@@ -12,7 +12,8 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <sstream>
|
//#include <sstream>
|
||||||
|
|
||||||
#if defined(HAVE_SYS_IOCTL_H)
|
#if defined(HAVE_SYS_IOCTL_H)
|
||||||
#define BSD_COMP /* needed for FIONREAD on Solaris2 */
|
#define BSD_COMP /* needed for FIONREAD on Solaris2 */
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
@@ -29,30 +30,223 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winsock.h>
|
#include <winsock.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
|
//#include <strstream>
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
# include <net/if.h>
|
//#include <net/if.h>
|
||||||
# include <sys/ioctl.h>
|
//#include <sys/ioctl.h>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "leak_dumper.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace Shared::Util;
|
using namespace Shared::Util;
|
||||||
|
|
||||||
namespace Shared{ namespace Platform{
|
namespace Shared{ namespace Platform{
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
|
||||||
|
#define socklen_t int
|
||||||
|
#define MAXHOSTNAME 254
|
||||||
|
#define PLATFORM_SOCKET_TRY_AGAIN WSAEWOULDBLOCK
|
||||||
|
#define PLATFORM_SOCKET_INPROGRESS WSAEINPROGRESS
|
||||||
|
#define PLATFORM_SOCKET_INTERRUPTED WSAEWOULDBLOCK
|
||||||
|
typedef SSIZE_T ssize_t;
|
||||||
|
|
||||||
|
//// Constants /////////////////////////////////////////////////////////
|
||||||
|
const int kBufferSize = 1024;
|
||||||
|
|
||||||
|
//// Statics ///////////////////////////////////////////////////////////
|
||||||
|
// List of Winsock error constants mapped to an interpretation string.
|
||||||
|
// Note that this list must remain sorted by the error constants'
|
||||||
|
// values, because we do a binary search on the list when looking up
|
||||||
|
// items.
|
||||||
|
|
||||||
|
static class ErrorEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int nID;
|
||||||
|
const char* pcMessage;
|
||||||
|
|
||||||
|
ErrorEntry(int id, const char* pc = 0) : nID(id), pcMessage(pc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const ErrorEntry& rhs)
|
||||||
|
{
|
||||||
|
return nID < rhs.nID;
|
||||||
|
}
|
||||||
|
|
||||||
|
} gaErrorList[] =
|
||||||
|
{
|
||||||
|
ErrorEntry(0, "No error"),
|
||||||
|
ErrorEntry(WSAEINTR, "Interrupted system call"),
|
||||||
|
ErrorEntry(WSAEBADF, "Bad file number"),
|
||||||
|
ErrorEntry(WSAEACCES, "Permission denied"),
|
||||||
|
ErrorEntry(WSAEFAULT, "Bad address"),
|
||||||
|
ErrorEntry(WSAEINVAL, "Invalid argument"),
|
||||||
|
ErrorEntry(WSAEMFILE, "Too many open sockets"),
|
||||||
|
ErrorEntry(WSAEWOULDBLOCK, "Operation would block"),
|
||||||
|
ErrorEntry(WSAEINPROGRESS, "Operation now in progress"),
|
||||||
|
ErrorEntry(WSAEALREADY, "Operation already in progress"),
|
||||||
|
ErrorEntry(WSAENOTSOCK, "Socket operation on non-socket"),
|
||||||
|
ErrorEntry(WSAEDESTADDRREQ, "Destination address required"),
|
||||||
|
ErrorEntry(WSAEMSGSIZE, "Message too long"),
|
||||||
|
ErrorEntry(WSAEPROTOTYPE, "Protocol wrong type for socket"),
|
||||||
|
ErrorEntry(WSAENOPROTOOPT, "Bad protocol option"),
|
||||||
|
ErrorEntry(WSAEPROTONOSUPPORT, "Protocol not supported"),
|
||||||
|
ErrorEntry(WSAESOCKTNOSUPPORT, "Socket type not supported"),
|
||||||
|
ErrorEntry(WSAEOPNOTSUPP, "Operation not supported on socket"),
|
||||||
|
ErrorEntry(WSAEPFNOSUPPORT, "Protocol family not supported"),
|
||||||
|
ErrorEntry(WSAEAFNOSUPPORT, "Address family not supported"),
|
||||||
|
ErrorEntry(WSAEADDRINUSE, "Address already in use"),
|
||||||
|
ErrorEntry(WSAEADDRNOTAVAIL, "Can't assign requested address"),
|
||||||
|
ErrorEntry(WSAENETDOWN, "Network is down"),
|
||||||
|
ErrorEntry(WSAENETUNREACH, "Network is unreachable"),
|
||||||
|
ErrorEntry(WSAENETRESET, "Net connection reset"),
|
||||||
|
ErrorEntry(WSAECONNABORTED, "Software caused connection abort"),
|
||||||
|
ErrorEntry(WSAECONNRESET, "Connection reset by peer"),
|
||||||
|
ErrorEntry(WSAENOBUFS, "No buffer space available"),
|
||||||
|
ErrorEntry(WSAEISCONN, "Socket is already connected"),
|
||||||
|
ErrorEntry(WSAENOTCONN, "Socket is not connected"),
|
||||||
|
ErrorEntry(WSAESHUTDOWN, "Can't send after socket shutdown"),
|
||||||
|
ErrorEntry(WSAETOOMANYREFS, "Too many references, can't splice"),
|
||||||
|
ErrorEntry(WSAETIMEDOUT, "Connection timed out"),
|
||||||
|
ErrorEntry(WSAECONNREFUSED, "Connection refused"),
|
||||||
|
ErrorEntry(WSAELOOP, "Too many levels of symbolic links"),
|
||||||
|
ErrorEntry(WSAENAMETOOLONG, "File name too long"),
|
||||||
|
ErrorEntry(WSAEHOSTDOWN, "Host is down"),
|
||||||
|
ErrorEntry(WSAEHOSTUNREACH, "No route to host"),
|
||||||
|
ErrorEntry(WSAENOTEMPTY, "Directory not empty"),
|
||||||
|
ErrorEntry(WSAEPROCLIM, "Too many processes"),
|
||||||
|
ErrorEntry(WSAEUSERS, "Too many users"),
|
||||||
|
ErrorEntry(WSAEDQUOT, "Disc quota exceeded"),
|
||||||
|
ErrorEntry(WSAESTALE, "Stale NFS file handle"),
|
||||||
|
ErrorEntry(WSAEREMOTE, "Too many levels of remote in path"),
|
||||||
|
ErrorEntry(WSASYSNOTREADY, "Network system is unavailable"),
|
||||||
|
ErrorEntry(WSAVERNOTSUPPORTED, "Winsock version out of range"),
|
||||||
|
ErrorEntry(WSANOTINITIALISED, "WSAStartup not yet called"),
|
||||||
|
ErrorEntry(WSAEDISCON, "Graceful shutdown in progress"),
|
||||||
|
ErrorEntry(WSAHOST_NOT_FOUND, "Host not found"),
|
||||||
|
ErrorEntry(WSANO_DATA, "No host data of that type was found")
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator<(const ErrorEntry& rhs1,const ErrorEntry& rhs2)
|
||||||
|
{
|
||||||
|
return rhs1.nID < rhs2.nID;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int kNumMessages = sizeof(gaErrorList) / sizeof(ErrorEntry);
|
||||||
|
|
||||||
|
//// WSAGetLastErrorMessage ////////////////////////////////////////////
|
||||||
|
// A function similar in spirit to Unix's perror() that tacks a canned
|
||||||
|
// interpretation of the value of WSAGetLastError() onto the end of a
|
||||||
|
// passed string, separated by a ": ". Generally, you should implement
|
||||||
|
// smarter error handling than this, but for default cases and simple
|
||||||
|
// programs, this function is sufficient.
|
||||||
|
//
|
||||||
|
// This function returns a pointer to an internal static buffer, so you
|
||||||
|
// must copy the data from this function before you call it again. It
|
||||||
|
// follows that this function is also not thread-safe.
|
||||||
|
const char* WSAGetLastErrorMessage(const char* pcMessagePrefix,
|
||||||
|
int nErrorID /* = 0 */)
|
||||||
|
{
|
||||||
|
// Build basic error string
|
||||||
|
static char acErrorBuffer[256];
|
||||||
|
std::ostrstream outs(acErrorBuffer, sizeof(acErrorBuffer));
|
||||||
|
outs << pcMessagePrefix << ": ";
|
||||||
|
|
||||||
|
// Tack appropriate canned message onto end of supplied message
|
||||||
|
// prefix. Note that we do a binary search here: gaErrorList must be
|
||||||
|
// sorted by the error constant's value.
|
||||||
|
ErrorEntry* pEnd = gaErrorList + kNumMessages;
|
||||||
|
ErrorEntry Target(nErrorID ? nErrorID : WSAGetLastError());
|
||||||
|
ErrorEntry* it = std::lower_bound(gaErrorList, pEnd, Target);
|
||||||
|
if ((it != pEnd) && (it->nID == Target.nID))
|
||||||
|
{
|
||||||
|
outs << it->pcMessage;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Didn't find error in list, so make up a generic one
|
||||||
|
outs << "unknown error";
|
||||||
|
}
|
||||||
|
outs << " (" << Target.nID << ")";
|
||||||
|
|
||||||
|
// Finish error message off and return it.
|
||||||
|
outs << std::ends;
|
||||||
|
acErrorBuffer[sizeof(acErrorBuffer) - 1] = '\0';
|
||||||
|
return acErrorBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::SocketManager Socket::socketManager;
|
||||||
|
|
||||||
|
Socket::SocketManager::SocketManager(){
|
||||||
|
WSADATA wsaData;
|
||||||
|
WORD wVersionRequested = MAKEWORD(2, 0);
|
||||||
|
WSAStartup(wVersionRequested, &wsaData);
|
||||||
|
//dont throw exceptions here, this is a static initializacion
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Winsock initialized.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::SocketManager::~SocketManager(){
|
||||||
|
WSACleanup();
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Winsock cleanup complete.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
typedef unsigned int UINT_PTR, *PUINT_PTR;
|
||||||
|
typedef UINT_PTR SOCKET;
|
||||||
|
#define INVALID_SOCKET (SOCKET)(~0)
|
||||||
|
|
||||||
|
#define PLATFORM_SOCKET_TRY_AGAIN EAGAIN
|
||||||
|
#define PLATFORM_SOCKET_INPROGRESS EINPROGRESS
|
||||||
|
#define PLATFORM_SOCKET_INTERRUPTED EINTR
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
int Socket::broadcast_portno = 61357;
|
int Socket::broadcast_portno = 61357;
|
||||||
BroadCastClientSocketThread *ClientSocket::broadCastClientThread = NULL;
|
BroadCastClientSocketThread *ClientSocket::broadCastClientThread = NULL;
|
||||||
|
|
||||||
|
int getLastSocketError() {
|
||||||
|
#ifndef WIN32
|
||||||
|
return errno;
|
||||||
|
#else
|
||||||
|
return WSAGetLastError();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
char * getLastSocketErrorText(int *errNumber=NULL) {
|
||||||
|
int errId = (errNumber != NULL ? *errNumber : getLastSocketError());
|
||||||
|
#ifndef WIN32
|
||||||
|
return strerror(errId);
|
||||||
|
#else
|
||||||
|
return WSAGetLastErrorMessage(errId);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
string getLastSocketErrorFormattedText(int *errNumber=NULL) {
|
||||||
|
int errId = (errNumber != NULL ? *errNumber : getLastSocketError());
|
||||||
|
string msg = "(Error: " + intToStr(errId) + " - [" + string(getLastSocketErrorText(&errId)) +"])";
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
// class Ip
|
// class Ip
|
||||||
// =====================================================
|
// =====================================================
|
||||||
@@ -425,9 +619,11 @@ std::vector<std::string> Socket::getLocalIPAddressList() {
|
|||||||
ipIdx++;
|
ipIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
|
||||||
// Now check all linux network devices
|
// Now check all linux network devices
|
||||||
for(int idx = 0; idx < 5; ++idx) {
|
for(int idx = 0; idx < 5; ++idx) {
|
||||||
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
PLATFORM_SOCKET fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
/* I want to get an IPv4 IP address */
|
/* I want to get an IPv4 IP address */
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
@@ -450,17 +646,37 @@ std::vector<std::string> Socket::getLocalIPAddressList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
return ipList;
|
return ipList;
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket::Socket(int sock){
|
bool Socket::isSocketValid(PLATFORM_SOCKET *validateSocket) const {
|
||||||
|
#ifdef WIN32
|
||||||
|
if(validateSocket == NULL) {
|
||||||
|
return (sock != INVALID_SOCKET);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (*validateSocket != INVALID_SOCKET);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(validateSocket == NULL) {
|
||||||
|
return (sock > 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return (*validateSocket > 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket::Socket(PLATFORM_SOCKET sock){
|
||||||
this->sock= sock;
|
this->sock= sock;
|
||||||
}
|
}
|
||||||
|
|
||||||
Socket::Socket()
|
Socket::Socket()
|
||||||
{
|
{
|
||||||
sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
if(sock < 0)
|
if(isSocketValid() == false)
|
||||||
{
|
{
|
||||||
throwException("Error creating socket");
|
throwException("Error creating socket");
|
||||||
}
|
}
|
||||||
@@ -479,19 +695,24 @@ void Socket::disconnectSocket()
|
|||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||||
|
|
||||||
if(sock > 0)
|
if(isSocketValid() == true)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling shutdown and close for socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] calling shutdown and close for socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||||
::shutdown(sock,2);
|
::shutdown(sock,2);
|
||||||
|
#ifndef WIN32
|
||||||
::close(sock);
|
::close(sock);
|
||||||
|
sock = INVALID_SOCKET;
|
||||||
|
#else
|
||||||
|
::closesocket(sock);
|
||||||
sock = -1;
|
sock = -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] END closing socket = %d...\n",__FILE__,__FUNCTION__,sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
|
||||||
bool Socket::hasDataToRead(std::map<int,bool> &socketTriggeredList)
|
bool Socket::hasDataToRead(std::map<PLATFORM_SOCKET,bool> &socketTriggeredList)
|
||||||
{
|
{
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
|
|
||||||
@@ -501,11 +722,11 @@ bool Socket::hasDataToRead(std::map<int,bool> &socketTriggeredList)
|
|||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
|
|
||||||
int imaxsocket = 0;
|
PLATFORM_SOCKET imaxsocket = 0;
|
||||||
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
|
for(std::map<PLATFORM_SOCKET,bool>::iterator itermap = socketTriggeredList.begin();
|
||||||
itermap != socketTriggeredList.end(); itermap++)
|
itermap != socketTriggeredList.end(); itermap++)
|
||||||
{
|
{
|
||||||
int socket = itermap->first;
|
PLATFORM_SOCKET socket = itermap->first;
|
||||||
if(socket > 0)
|
if(socket > 0)
|
||||||
{
|
{
|
||||||
FD_SET(socket, &rfds);
|
FD_SET(socket, &rfds);
|
||||||
@@ -523,7 +744,7 @@ bool Socket::hasDataToRead(std::map<int,bool> &socketTriggeredList)
|
|||||||
int retval = select(imaxsocket + 1, &rfds, NULL, NULL, &tv);
|
int retval = select(imaxsocket + 1, &rfds, NULL, NULL, &tv);
|
||||||
if(retval < 0)
|
if(retval < 0)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] ERROR SELECTING SOCKET DATA retval = %d errno = %d [%s]\n",__FILE__,__FUNCTION__,retval,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] ERROR SELECTING SOCKET DATA retval = %d error = %s\n",__FILE__,__FUNCTION__,retval,getLastSocketErrorFormattedText().c_str());
|
||||||
}
|
}
|
||||||
else if(retval)
|
else if(retval)
|
||||||
{
|
{
|
||||||
@@ -531,10 +752,10 @@ bool Socket::hasDataToRead(std::map<int,bool> &socketTriggeredList)
|
|||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] select detected data imaxsocket = %d...\n",__FILE__,__FUNCTION__,imaxsocket);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] select detected data imaxsocket = %d...\n",__FILE__,__FUNCTION__,imaxsocket);
|
||||||
|
|
||||||
for(std::map<int,bool>::iterator itermap = socketTriggeredList.begin();
|
for(std::map<PLATFORM_SOCKET,bool>::iterator itermap = socketTriggeredList.begin();
|
||||||
itermap != socketTriggeredList.end(); itermap++)
|
itermap != socketTriggeredList.end(); itermap++)
|
||||||
{
|
{
|
||||||
int socket = itermap->first;
|
PLATFORM_SOCKET socket = itermap->first;
|
||||||
if (FD_ISSET(socket, &rfds))
|
if (FD_ISSET(socket, &rfds))
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] FD_ISSET true for socket %d...\n",__FUNCTION__,socket);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s] FD_ISSET true for socket %d...\n",__FUNCTION__,socket);
|
||||||
@@ -560,7 +781,7 @@ bool Socket::hasDataToRead()
|
|||||||
return Socket::hasDataToRead(sock) ;
|
return Socket::hasDataToRead(sock) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Socket::hasDataToRead(int socket)
|
bool Socket::hasDataToRead(PLATFORM_SOCKET socket)
|
||||||
{
|
{
|
||||||
bool bResult = false;
|
bool bResult = false;
|
||||||
|
|
||||||
@@ -607,15 +828,18 @@ int Socket::getDataToRead(){
|
|||||||
|
|
||||||
//retval = select(sock + 1, &rfds, NULL, NULL, &tv);
|
//retval = select(sock + 1, &rfds, NULL, NULL, &tv);
|
||||||
//if(retval)
|
//if(retval)
|
||||||
if(sock > 0)
|
if(isSocketValid() == true)
|
||||||
{
|
{
|
||||||
/* ioctl isn't posix, but the following seems to work on all modern
|
/* ioctl isn't posix, but the following seems to work on all modern
|
||||||
* unixes */
|
* unixes */
|
||||||
|
#ifndef WIN32
|
||||||
int err = ioctl(sock, FIONREAD, &size);
|
int err = ioctl(sock, FIONREAD, &size);
|
||||||
|
#else
|
||||||
if(err < 0 && errno != EAGAIN)
|
int err= ioctlsocket(sock, FIONREAD, &size);
|
||||||
|
#endif
|
||||||
|
if(err < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] ERROR PEEKING SOCKET DATA, err = %d errno = %d [%s]\n",__FILE__,__FUNCTION__,err,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] ERROR PEEKING SOCKET DATA, err = %d %s\n",__FILE__,__FUNCTION__,err,getLastSocketErrorFormattedText().c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
}
|
}
|
||||||
else if(err == 0)
|
else if(err == 0)
|
||||||
@@ -629,21 +853,21 @@ int Socket::getDataToRead(){
|
|||||||
|
|
||||||
int Socket::send(const void *data, int dataSize) {
|
int Socket::send(const void *data, int dataSize) {
|
||||||
ssize_t bytesSent= 0;
|
ssize_t bytesSent= 0;
|
||||||
if(sock > 0)
|
if(isSocketValid() == true)
|
||||||
{
|
{
|
||||||
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
|
bytesSent = ::send(sock, reinterpret_cast<const char*>(data), dataSize, 0);
|
||||||
}
|
}
|
||||||
if(bytesSent < 0 && errno != EAGAIN)
|
if(bytesSent < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] ERROR WRITING SOCKET DATA, err = %d errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesSent,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] ERROR WRITING SOCKET DATA, err = %d error = %s\n",__FILE__,__FUNCTION__,bytesSent,getLastSocketErrorFormattedText().c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
}
|
}
|
||||||
else if(bytesSent < 0 && errno == EAGAIN)
|
else if(bytesSent < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #1 EAGAIN during send, trying again...\n",__FILE__,__FUNCTION__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #1 EAGAIN during send, trying again...\n",__FILE__,__FUNCTION__);
|
||||||
|
|
||||||
time_t tStartTimer = time(NULL);
|
time_t tStartTimer = time(NULL);
|
||||||
while((bytesSent < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
while((bytesSent < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||||
{
|
{
|
||||||
if(Socket::isWritable(true) == true)
|
if(Socket::isWritable(true) == true)
|
||||||
{
|
{
|
||||||
@@ -655,10 +879,10 @@ int Socket::send(const void *data, int dataSize) {
|
|||||||
}
|
}
|
||||||
if(bytesSent <= 0)
|
if(bytesSent <= 0)
|
||||||
{
|
{
|
||||||
int iErr = errno;
|
int iErr = getLastSocketError();
|
||||||
disconnectSocket();
|
disconnectSocket();
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesSent,iErr,strerror(iErr));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] DISCONNECTED SOCKET error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,bytesSent,getLastSocketErrorFormattedText(&iErr).c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -671,21 +895,21 @@ int Socket::receive(void *data, int dataSize)
|
|||||||
{
|
{
|
||||||
ssize_t bytesReceived = 0;
|
ssize_t bytesReceived = 0;
|
||||||
|
|
||||||
if(sock > 0)
|
if(isSocketValid() == true)
|
||||||
{
|
{
|
||||||
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
|
bytesReceived = recv(sock, reinterpret_cast<char*>(data), dataSize, 0);
|
||||||
}
|
}
|
||||||
if(bytesReceived < 0 && errno != EAGAIN)
|
if(bytesReceived < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesReceived,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,bytesReceived,getLastSocketErrorFormattedText().c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
}
|
}
|
||||||
else if(bytesReceived < 0 && errno == EAGAIN)
|
else if(bytesReceived < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #1 EAGAIN during receive, trying again...\n",__FILE__,__FUNCTION__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #1 EAGAIN during receive, trying again...\n",__FILE__,__FUNCTION__);
|
||||||
|
|
||||||
time_t tStartTimer = time(NULL);
|
time_t tStartTimer = time(NULL);
|
||||||
while((bytesReceived < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
while((bytesReceived < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||||
{
|
{
|
||||||
if(Socket::isReadable() == true)
|
if(Socket::isReadable() == true)
|
||||||
{
|
{
|
||||||
@@ -698,10 +922,10 @@ int Socket::receive(void *data, int dataSize)
|
|||||||
|
|
||||||
if(bytesReceived <= 0)
|
if(bytesReceived <= 0)
|
||||||
{
|
{
|
||||||
int iErr = errno;
|
int iErr = getLastSocketError();
|
||||||
disconnectSocket();
|
disconnectSocket();
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,bytesReceived,iErr,strerror(iErr));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s\n",__FILE__,__FUNCTION__,bytesReceived,getLastSocketErrorFormattedText(&iErr).c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
}
|
}
|
||||||
return static_cast<int>(bytesReceived);
|
return static_cast<int>(bytesReceived);
|
||||||
@@ -709,23 +933,23 @@ int Socket::receive(void *data, int dataSize)
|
|||||||
|
|
||||||
int Socket::peek(void *data, int dataSize){
|
int Socket::peek(void *data, int dataSize){
|
||||||
ssize_t err = 0;
|
ssize_t err = 0;
|
||||||
if(sock > 0)
|
if(isSocketValid() == true)
|
||||||
{
|
{
|
||||||
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
|
err = recv(sock, reinterpret_cast<char*>(data), dataSize, MSG_PEEK);
|
||||||
}
|
}
|
||||||
if(err < 0 && errno != EAGAIN)
|
if(err < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] ERROR PEEKING SOCKET DATA error while sending socket data, bytesSent = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] ERROR PEEKING SOCKET DATA error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,err,getLastSocketErrorFormattedText().c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
|
|
||||||
disconnectSocket();
|
disconnectSocket();
|
||||||
}
|
}
|
||||||
else if(err < 0 && errno == EAGAIN)
|
else if(err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #1 EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #1 EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__);
|
||||||
|
|
||||||
time_t tStartTimer = time(NULL);
|
time_t tStartTimer = time(NULL);
|
||||||
while((err < 0 && errno == EAGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
while((err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && (difftime(time(NULL),tStartTimer) <= 5))
|
||||||
{
|
{
|
||||||
if(Socket::isReadable() == true)
|
if(Socket::isReadable() == true)
|
||||||
{
|
{
|
||||||
@@ -738,10 +962,10 @@ int Socket::peek(void *data, int dataSize){
|
|||||||
|
|
||||||
if(err <= 0)
|
if(err <= 0)
|
||||||
{
|
{
|
||||||
int iErr = errno;
|
int iErr = getLastSocketError();
|
||||||
disconnectSocket();
|
disconnectSocket();
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] DISCONNECTED SOCKET error while peeking socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,err,iErr,strerror(iErr));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] DISCONNECTED SOCKET error while peeking socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,err,getLastSocketErrorFormattedText(&iErr).c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -752,8 +976,13 @@ void Socket::setBlock(bool block){
|
|||||||
setBlock(block,this->sock);
|
setBlock(block,this->sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Socket::setBlock(bool block, int socket){
|
void Socket::setBlock(bool block, PLATFORM_SOCKET socket){
|
||||||
|
#ifndef WIN32
|
||||||
int err= fcntl(socket, F_SETFL, block ? 0 : O_NONBLOCK);
|
int err= fcntl(socket, F_SETFL, block ? 0 : O_NONBLOCK);
|
||||||
|
#else
|
||||||
|
u_long iMode= !block;
|
||||||
|
int err= ioctlsocket(socket, FIONBIO, &iMode);
|
||||||
|
#endif
|
||||||
if(err < 0){
|
if(err < 0){
|
||||||
throwException("Error setting I/O mode for socket");
|
throwException("Error setting I/O mode for socket");
|
||||||
}
|
}
|
||||||
@@ -761,9 +990,12 @@ void Socket::setBlock(bool block, int socket){
|
|||||||
|
|
||||||
bool Socket::isReadable()
|
bool Socket::isReadable()
|
||||||
{
|
{
|
||||||
if(sock <= 0) return false;
|
if(isSocketValid() == false) return false;
|
||||||
|
#ifndef WIN32
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
#else
|
||||||
|
TIMEVAL tv;
|
||||||
|
#endif
|
||||||
tv.tv_sec= 0;
|
tv.tv_sec= 0;
|
||||||
tv.tv_usec= 1;
|
tv.tv_usec= 1;
|
||||||
|
|
||||||
@@ -779,7 +1011,7 @@ bool Socket::isReadable()
|
|||||||
lastDebugEvent = time(NULL);
|
lastDebugEvent = time(NULL);
|
||||||
|
|
||||||
//throwException("Error selecting socket");
|
//throwException("Error selecting socket");
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] error while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,i,getLastSocketErrorFormattedText().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//return (i == 1 && FD_ISSET(sock, &set));
|
//return (i == 1 && FD_ISSET(sock, &set));
|
||||||
@@ -788,9 +1020,13 @@ bool Socket::isReadable()
|
|||||||
|
|
||||||
bool Socket::isWritable(bool waitOnDelayedResponse)
|
bool Socket::isWritable(bool waitOnDelayedResponse)
|
||||||
{
|
{
|
||||||
if(sock <= 0) return false;
|
if(isSocketValid() == false) return false;
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
#else
|
||||||
|
TIMEVAL tv;
|
||||||
|
#endif
|
||||||
tv.tv_sec= 0;
|
tv.tv_sec= 0;
|
||||||
tv.tv_usec= 1;
|
tv.tv_usec= 1;
|
||||||
|
|
||||||
@@ -808,7 +1044,7 @@ bool Socket::isWritable(bool waitOnDelayedResponse)
|
|||||||
{
|
{
|
||||||
lastDebugEvent = time(NULL);
|
lastDebugEvent = time(NULL);
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] error while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] error while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,i,getLastSocketErrorFormattedText().c_str());
|
||||||
}
|
}
|
||||||
waitOnDelayedResponse = false;
|
waitOnDelayedResponse = false;
|
||||||
|
|
||||||
@@ -819,7 +1055,7 @@ bool Socket::isWritable(bool waitOnDelayedResponse)
|
|||||||
if(difftime(time(NULL),lastDebugEvent) >= 1)
|
if(difftime(time(NULL),lastDebugEvent) >= 1)
|
||||||
{
|
{
|
||||||
lastDebugEvent = time(NULL);
|
lastDebugEvent = time(NULL);
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] TIMEOUT while selecting socket data, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,i,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s] TIMEOUT while selecting socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,i,getLastSocketErrorFormattedText().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(waitOnDelayedResponse == false)
|
if(waitOnDelayedResponse == false)
|
||||||
@@ -885,10 +1121,9 @@ string Socket::getIp() {
|
|||||||
intToStr(address[3]);
|
intToStr(address[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Socket::throwException(const string &str){
|
void Socket::throwException(string str){
|
||||||
std::stringstream msg;
|
string msg = str + " " + getLastSocketErrorFormattedText();
|
||||||
msg << str << " (Error: " << strerror(errno) << ")";
|
throw runtime_error(msg);
|
||||||
throw runtime_error(msg.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===============================================
|
// ===============================================
|
||||||
@@ -962,19 +1197,22 @@ void ClientSocket::connect(const Ip &ip, int port)
|
|||||||
addr.sin_addr.s_addr= inet_addr(ip.getString().c_str());
|
addr.sin_addr.s_addr= inet_addr(ip.getString().c_str());
|
||||||
addr.sin_port= htons(port);
|
addr.sin_port= htons(port);
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Connecting to host [%s] on port = %d\n", ip.getString().c_str(),port);
|
||||||
|
|
||||||
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
|
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
|
||||||
if(err < 0)
|
if(err < 0)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #2 Error connecting socket for IP: %s for Port: %d err = %d errno = %d [%s]\n",__FILE__,__FUNCTION__,ip.getString().c_str(),port,err,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,ip.getString().c_str(),port,err,getLastSocketErrorFormattedText().c_str());
|
||||||
|
|
||||||
if (errno == EINPROGRESS)
|
if (getLastSocketError() == PLATFORM_SOCKET_INPROGRESS ||
|
||||||
|
getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
fd_set myset;
|
fd_set myset;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int valopt;
|
int valopt;
|
||||||
socklen_t lon;
|
socklen_t lon;
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] EINPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@@ -986,9 +1224,9 @@ void ClientSocket::connect(const Ip &ip, int port)
|
|||||||
|
|
||||||
err = select(sock+1, NULL, &myset, NULL, &tv);
|
err = select(sock+1, NULL, &myset, NULL, &tv);
|
||||||
|
|
||||||
if (err < 0 && errno != EINTR)
|
if (err < 0 && getLastSocketError() != PLATFORM_SOCKET_INTERRUPTED)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error connecting %d - [%s]\n",__FILE__,__FUNCTION__,errno, strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error connecting %s\n",__FILE__,__FUNCTION__,getLastSocketErrorFormattedText().c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -996,9 +1234,13 @@ void ClientSocket::connect(const Ip &ip, int port)
|
|||||||
{
|
{
|
||||||
// Socket selected for write
|
// Socket selected for write
|
||||||
lon = sizeof(int);
|
lon = sizeof(int);
|
||||||
|
#ifndef WIN32
|
||||||
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0)
|
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0)
|
||||||
|
#else
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)(&valopt), &lon) < 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error in getsockopt() %d - [%s]\n",__FILE__,__FUNCTION__,errno, strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error in getsockopt() %s\n",__FILE__,__FUNCTION__,getLastSocketErrorFormattedText().c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1011,7 +1253,7 @@ void ClientSocket::connect(const Ip &ip, int port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Apparent recovery for connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Apparent recovery for connection sock = %d, err = %d\n",__FILE__,__FUNCTION__,sock,err);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1028,15 +1270,19 @@ void ClientSocket::connect(const Ip &ip, int port)
|
|||||||
|
|
||||||
if(err < 0)
|
if(err < 0)
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Before END sock = %d, err = %d, errno = %d [%s]\n",__FILE__,__FUNCTION__,sock,err,errno,strerror(errno));
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Before END sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str());
|
||||||
//throwException(szBuf);
|
//throwException(szBuf);
|
||||||
disconnectSocket();
|
disconnectSocket();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Valid recovery for connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Valid recovery for connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Connected to host [%s] on port = %d sock = %d err = %d", ip.getString().c_str(),port,err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
@@ -1122,7 +1368,7 @@ void BroadCastClientSocketThread::execute() {
|
|||||||
short port; // The port for the broadcast.
|
short port; // The port for the broadcast.
|
||||||
struct sockaddr_in bcSender; // local socket address for the broadcast.
|
struct sockaddr_in bcSender; // local socket address for the broadcast.
|
||||||
struct sockaddr_in bcaddr; // The broadcast address for the receiver.
|
struct sockaddr_in bcaddr; // The broadcast address for the receiver.
|
||||||
int bcfd; // The file descriptor used for the broadcast.
|
PLATFORM_SOCKET bcfd; // The file descriptor used for the broadcast.
|
||||||
bool one = true; // Parameter for "setscokopt".
|
bool one = true; // Parameter for "setscokopt".
|
||||||
char buff[10024]; // Buffers the data to be broadcasted.
|
char buff[10024]; // Buffers the data to be broadcasted.
|
||||||
socklen_t alen;
|
socklen_t alen;
|
||||||
@@ -1133,7 +1379,7 @@ void BroadCastClientSocketThread::execute() {
|
|||||||
// Prepare to receive the broadcast.
|
// Prepare to receive the broadcast.
|
||||||
bcfd = socket(AF_INET, SOCK_DGRAM, 0);
|
bcfd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
if( bcfd <= 0 ) {
|
if( bcfd <= 0 ) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"socket failed: %d\n", errno);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"socket failed: %s\n", getLastSocketErrorFormattedText().c_str());
|
||||||
//exit(-1);
|
//exit(-1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1144,10 +1390,13 @@ void BroadCastClientSocketThread::execute() {
|
|||||||
bcaddr.sin_port = port;
|
bcaddr.sin_port = port;
|
||||||
|
|
||||||
int val = 1;
|
int val = 1;
|
||||||
|
#ifndef WIN32
|
||||||
setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||||
|
#else
|
||||||
|
setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
||||||
|
#endif
|
||||||
if(bind( bcfd, (struct sockaddr *)&bcaddr, sizeof(bcaddr) ) < 0 ) {
|
if(bind( bcfd, (struct sockaddr *)&bcaddr, sizeof(bcaddr) ) < 0 ) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"bind failed: %d\n", errno);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"bind failed: %s\n", getLastSocketErrorFormattedText().c_str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
@@ -1165,7 +1414,7 @@ void BroadCastClientSocketThread::execute() {
|
|||||||
alen = sizeof(struct sockaddr);
|
alen = sizeof(struct sockaddr);
|
||||||
if( (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) <= 0 )
|
if( (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) <= 0 )
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"recvfrom failed: %d\n", errno);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"recvfrom failed: %s\n", getLastSocketErrorFormattedText().c_str());
|
||||||
//exit(-1);
|
//exit(-1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1291,13 +1540,18 @@ void ServerSocket::bind(int port)
|
|||||||
addr.sin_port= htons(port);
|
addr.sin_port= htons(port);
|
||||||
|
|
||||||
int val = 1;
|
int val = 1;
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||||
|
#else
|
||||||
|
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
||||||
|
#endif
|
||||||
|
|
||||||
int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
|
int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
|
||||||
if(err < 0)
|
if(err < 0)
|
||||||
{
|
{
|
||||||
char szBuf[1024]="";
|
char szBuf[1024]="";
|
||||||
sprintf(szBuf, "In [%s::%s] Error binding socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
sprintf(szBuf, "In [%s::%s] Error binding socket sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str());
|
||||||
throwException(szBuf);
|
throwException(szBuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1308,7 +1562,7 @@ void ServerSocket::listen(int connectionQueueSize)
|
|||||||
if(err < 0)
|
if(err < 0)
|
||||||
{
|
{
|
||||||
char szBuf[1024]="";
|
char szBuf[1024]="";
|
||||||
sprintf(szBuf, "In [%s::%s] Error listening socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno);
|
sprintf(szBuf, "In [%s::%s] Error listening socket sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str());
|
||||||
throwException(szBuf);
|
throwException(szBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1325,13 +1579,13 @@ void ServerSocket::listen(int connectionQueueSize)
|
|||||||
|
|
||||||
Socket *ServerSocket::accept()
|
Socket *ServerSocket::accept()
|
||||||
{
|
{
|
||||||
int newSock= ::accept(sock, NULL, NULL);
|
PLATFORM_SOCKET newSock= ::accept(sock, NULL, NULL);
|
||||||
if(newSock < 0)
|
if(isSocketValid(&newSock) == false)
|
||||||
{
|
{
|
||||||
char szBuf[1024]="";
|
char szBuf[1024]="";
|
||||||
sprintf(szBuf, "In [%s::%s] Error accepting socket connection sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,newSock,errno);
|
sprintf(szBuf, "In [%s::%s] Error accepting socket connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,newSock,getLastSocketErrorFormattedText().c_str());
|
||||||
|
|
||||||
if(errno == EAGAIN)
|
if(getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -1341,7 +1595,6 @@ Socket *ServerSocket::accept()
|
|||||||
return new Socket(newSock);
|
return new Socket(newSock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BroadCastSocketThread::BroadCastSocketThread() {
|
BroadCastSocketThread::BroadCastSocketThread() {
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
@@ -1418,17 +1671,14 @@ void BroadCastSocketThread::execute() {
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
const int MAX_NIC_COUNT = 10;
|
const int MAX_NIC_COUNT = 10;
|
||||||
//unsigned int tbcaddr; // The broadcast address.
|
|
||||||
short port; // The port for the broadcast.
|
short port; // The port for the broadcast.
|
||||||
struct sockaddr_in bcLocal[MAX_NIC_COUNT]; // local socket address for the broadcast.
|
struct sockaddr_in bcLocal[MAX_NIC_COUNT]; // local socket address for the broadcast.
|
||||||
//struct sockaddr_in bcaddr; // The broadcast address for the receiver.
|
PLATFORM_SOCKET bcfd[MAX_NIC_COUNT]; // The socket used for the broadcast.
|
||||||
int bcfd[MAX_NIC_COUNT]; // The socket used for the broadcast.
|
|
||||||
bool one = true; // Parameter for "setscokopt".
|
bool one = true; // Parameter for "setscokopt".
|
||||||
int pn; // The number of the packet broadcasted.
|
int pn; // The number of the packet broadcasted.
|
||||||
char buff[1024]; // Buffers the data to be broadcasted.
|
char buff[1024]; // Buffers the data to be broadcasted.
|
||||||
char myhostname[100]; // hostname of local machine
|
char myhostname[100]; // hostname of local machine
|
||||||
char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to
|
char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to
|
||||||
//struct in_addr myaddr; // My host address in net format
|
|
||||||
struct hostent* myhostent;
|
struct hostent* myhostent;
|
||||||
char * ptr; // some transient vars
|
char * ptr; // some transient vars
|
||||||
int len,i;
|
int len,i;
|
||||||
@@ -1455,12 +1705,12 @@ void BroadCastSocketThread::execute() {
|
|||||||
bcLocal[idx].sin_port = port; // We are letting the OS fill in the port number for the local machine.
|
bcLocal[idx].sin_port = port; // We are letting the OS fill in the port number for the local machine.
|
||||||
bcfd[idx] = socket( AF_INET, SOCK_DGRAM, 0 );
|
bcfd[idx] = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
if( bcfd[idx] <= 0 ) {
|
if( bcfd[idx] <= 0 ) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Unable to allocate broadcast socket [%s]: %d\n", subnetmask[idx], errno);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Unable to allocate broadcast socket [%s]: %s\n", subnetmask[idx], getLastSocketErrorFormattedText().c_str());
|
||||||
//exit(-1);
|
//exit(-1);
|
||||||
}
|
}
|
||||||
// Mark the socket for broadcast.
|
// Mark the socket for broadcast.
|
||||||
else if( setsockopt( bcfd[idx], SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) ) < 0 ) {
|
else if( setsockopt( bcfd[idx], SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) ) < 0 ) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not set socket to broadcast [%s]: %d\n", subnetmask[idx], errno);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not set socket to broadcast [%s]: %s\n", subnetmask[idx], getLastSocketErrorFormattedText().c_str());
|
||||||
//exit(-1);
|
//exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1490,7 +1740,7 @@ void BroadCastSocketThread::execute() {
|
|||||||
//if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
|
//if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
|
||||||
if( sendto( bcfd[idx], buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcLocal[idx], sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
|
if( sendto( bcfd[idx], buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcLocal[idx], sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 )
|
||||||
{
|
{
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %d\n", errno);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %s\n", getLastSocketErrorFormattedText().c_str());
|
||||||
//exit(-1);
|
//exit(-1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1507,7 +1757,7 @@ void BroadCastSocketThread::execute() {
|
|||||||
}
|
}
|
||||||
sleep( 100 ); // send out broadcast every 1 seconds
|
sleep( 100 ); // send out broadcast every 1 seconds
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
catch(const exception &ex) {
|
catch(const exception &ex) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
|
Reference in New Issue
Block a user