summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2011-11-26 18:35:11 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2011-11-26 18:35:11 +0800
commite340dacb3015693cdb30abfe9f4674c1d4f43441 (patch)
tree5c53e788d30b9ae774a765bae09e6a21a2563de8
parent2d305304ee98b426007bed29de3491e6a5a3a716 (diff)
SexyAppFramework: Extent the socket wrapper for more advanced use
-rw-r--r--osframework/source/SexyAppFramework/SexySocket.cpp72
-rw-r--r--osframework/source/SexyAppFramework/SexySocket.h30
2 files changed, 86 insertions, 16 deletions
diff --git a/osframework/source/SexyAppFramework/SexySocket.cpp b/osframework/source/SexyAppFramework/SexySocket.cpp
index 28f81ce..9359578 100644
--- a/osframework/source/SexyAppFramework/SexySocket.cpp
+++ b/osframework/source/SexyAppFramework/SexySocket.cpp
@@ -17,19 +17,20 @@ typedef char raw_type; // Type used for raw data on this platform
#include <arpa/inet.h> // For inet_addr()
#include <unistd.h> // For close()
#include <netinet/in.h> // For sockaddr_in
-typedef void raw_type; // Type used for raw data on this platform
+#include <fcntl.h>
+#include <errno.h> // For errno
-#include <errno.h> // For errno
+typedef void raw_type; // Type used for raw data on this platform
#endif
#include <string.h>
#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
using namespace std;
-#ifdef WIN32
static bool initialized = false;
-#endif
using namespace Sexy;
@@ -40,33 +41,39 @@ static bool fillAddr(const string &address, unsigned short port,
memset(&addr, 0, sizeof(addr)); // Zero out address structure
addr.sin_family = AF_INET; // Internet address
- hostent *host; // Resolve name
- host = gethostbyname(address.c_str());
- if (!host)
- return false;
- addr.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);
+ if (!address.empty())
+ {
+ hostent *host; // Resolve name
+ host = gethostbyname(address.c_str());
+ if (!host)
+ return false;
+ addr.sin_addr.s_addr = *((unsigned long *) host->h_addr_list[0]);
+ }
addr.sin_port = htons(port); // Assign port in network byte order
+ return true;
}
// Socket Code
Socket::Socket(int type, int protocol)
{
-#ifdef WIN32
if (!initialized)
{
+#ifdef WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 0); // Request WinSock v2.0
WSAStartup(wVersionRequested, &wsaData);
+#else
+ signal(SIGPIPE, SIG_IGN);
+#endif
initialized = true;
}
-#endif
// Make a new socket
mSock = socket(PF_INET, type, protocol);
- mHasError = mSock >=0;
+ mHasError = mSock < 0;
}
Socket::Socket(int sockDesc)
@@ -88,6 +95,11 @@ bool Socket::hasError()
return mHasError;
}
+int Socket::getSocket()
+{
+ return mSock;
+}
+
string Socket::getLocalAddress()
{
sockaddr_in addr;
@@ -136,6 +148,35 @@ bool Socket::setLocalAddressAndPort(const string &localAddress,
return true;
}
+bool Socket::setAddressReuse(bool reuse)
+{
+ unsigned long op = reuse ? 1 : 0;
+
+ if (setsockopt (mSock, SOL_SOCKET, SO_REUSEADDR, (raw_type *)&op,
+ sizeof(unsigned long)) == -1)
+ return false;
+ return true;
+}
+
+bool Socket::setBlockingMode(bool block)
+{
+#ifdef WIN32
+ unsigned long op = block ? 1 : 0;
+ ioctlsocket (mSock, FIONBIO, &op);
+#else
+ int flags;
+
+ flags = fcntl(mSock, F_GETFL);
+ if (block)
+ flags &= ~O_NONBLOCK;
+ else
+ flags |= O_NONBLOCK;
+ if (fcntl(mSock, F_SETFL, flags) < 0)
+ return false;
+#endif
+ return true;
+}
+
void Socket::cleanup()
{
#ifdef WIN32
@@ -184,7 +225,10 @@ bool CommunicatingSocket::connect(const string &foreignAddress,
bool CommunicatingSocket::send(const void *buffer, int bufferLen)
{
- if (::send(mSock, (raw_type *) buffer, bufferLen, 0) < 0)
+ int ret;
+
+ ret = ::send(mSock, (raw_type *) buffer, bufferLen, 0);
+ if (ret < 0)
return false;
return true;
}
@@ -239,6 +283,7 @@ TCPSocket::TCPSocket(int newConnSD) : CommunicatingSocket(newConnSD)
TCPServerSocket::TCPServerSocket(unsigned short localPort, int queueLen)
: Socket(SOCK_STREAM, IPPROTO_TCP)
{
+ setAddressReuse(true);
setLocalPort(localPort);
setListen(queueLen);
}
@@ -247,6 +292,7 @@ TCPServerSocket::TCPServerSocket(const string &localAddress,
unsigned short localPort, int queueLen)
: Socket(SOCK_STREAM, IPPROTO_TCP)
{
+ setAddressReuse(true);
setLocalAddressAndPort(localAddress, localPort);
setListen(queueLen);
}
diff --git a/osframework/source/SexyAppFramework/SexySocket.h b/osframework/source/SexyAppFramework/SexySocket.h
index de13449..8383b21 100644
--- a/osframework/source/SexyAppFramework/SexySocket.h
+++ b/osframework/source/SexyAppFramework/SexySocket.h
@@ -7,9 +7,15 @@ using namespace std;
namespace Sexy {
-/**
- * Base class representing basic communication endpoint
- */
+ /**
+ * Base class representing basic communication endpoint
+ */
+ enum SocketError {
+ SOCK_OK,
+ SOCK_WOULD_BLOCK,
+ SOCK_IN_PROGRESS
+ };
+
class Socket {
public:
/**
@@ -24,6 +30,12 @@ namespace Sexy {
bool hasError();
/**
+ * Get the socket descriptor
+ * @return the socket descriptor
+ */
+ int getSocket();
+
+ /**
* Get the local address
* @return local address of socket
*/
@@ -53,6 +65,18 @@ namespace Sexy {
unsigned short localPort = 0);
/**
+ * Set SO_REUSEADDR bit
+ *
+ * @param reuse enable/disable the address reuse
+ */
+ bool setAddressReuse(bool reuse);
+
+ /**
+ *
+ */
+ bool setBlockingMode(bool block);
+
+ /**
* If WinSock, unload the WinSock DLLs; otherwise do nothing. We ignore
* this in our sample client code but include it in the library for
* completeness. If you are running on Windows and you are concerned