40#include "blocxx/BLOCXX_config.h"
42#if defined(BLOCXX_WIN32)
70 ::WSAStartup(MAKEWORD(2,2), &wsaData);
80SockInitializer _sockInitializer;
84_closeSocket(SOCKET& sockfd)
88 ::closesocket(sockfd);
97 SOCKET sd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
98 if (sd == SOCKET_ERROR)
104 INTERFACE_INFO interfaceList[20];
105 unsigned long nBytesReturned;
106 if (::WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &interfaceList,
107 sizeof(interfaceList), &nBytesReturned, 0, 0) != SOCKET_ERROR)
109 int nNumInterfaces = nBytesReturned /
sizeof(INTERFACE_INFO);
110 for (
int i = 0;
i < nNumInterfaces; ++
i)
112 u_long nFlags = interfaceList[
i].iiFlags;
116 ::memcpy(&addr, &(interfaceList[
i].iiAddress),
sizeof(addr));
117 if (!(nFlags & IFF_LOOPBACK))
147SocketBaseImpl::waitForEvent(HANDLE eventArg,
int secsToTimeout)
149 DWORD timeout = (secsToTimeout != -1)
150 ?
static_cast<DWORD
>(secsToTimeout * 1000)
158 events[1] = eventArg;
160 DWORD index = ::WaitForMultipleObjects(
175 index -= WAIT_OBJECT_0;
179 ::ResetEvent(eventArg);
181 cc =
static_cast<int>(index);
187 switch(::WaitForSingleObject(eventArg, timeout))
190 ::ResetEvent(eventArg);
205#pragma warning (push)
206#pragma warning (disable: 4355)
212 , m_isConnected(false)
217 , m_recvTimeoutExprd(false)
220 , m_out(&m_streamBuf)
221 , m_inout(&m_streamBuf)
222 , m_recvTimeout(Timeout::infinite)
223 , m_sendTimeout(Timeout::infinite)
224 , m_connectTimeout(Timeout::relative(0))
226 m_out.exceptions(std::ios::badbit);
227 m_inout.exceptions(std::ios::badbit);
228 m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
232SocketBaseImpl::SocketBaseImpl(SocketHandle_t fd,
233 SocketAddress::AddressType addrType)
236 , m_isConnected(true)
238 , m_localAddress(SocketAddress::getAnyLocalHost())
239 , m_peerAddress(SocketAddress::allocEmptyAddress(addrType))
241 , m_recvTimeoutExprd(false)
244 , m_out(&m_streamBuf)
245 , m_inout(&m_streamBuf)
246 , m_recvTimeout(Timeout::infinite)
247 , m_sendTimeout(Timeout::infinite)
248 , m_connectTimeout(Timeout::relative(0))
252 m_out.exceptions(std::ios::badbit);
253 m_inout.exceptions(std::ios::badbit);
254 m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
259SocketBaseImpl::SocketBaseImpl(
const SocketAddress& addr)
262 , m_isConnected(false)
264 , m_localAddress(SocketAddress::getAnyLocalHost())
265 , m_peerAddress(addr)
267 , m_recvTimeoutExprd(false)
270 , m_out(&m_streamBuf)
271 , m_inout(&m_streamBuf)
272 , m_recvTimeout(Timeout::infinite)
273 , m_sendTimeout(Timeout::infinite)
274 , m_connectTimeout(Timeout::relative(0))
276 m_out.exceptions(std::ios::badbit);
277 m_inout.exceptions(std::ios::badbit);
278 m_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
280 connect(m_peerAddress);
286SocketBaseImpl::~SocketBaseImpl()
296 ::CloseHandle(m_event);
300SocketBaseImpl::getSelectObj()
const
304 st.sockfd = m_sockfd;
306 st.networkevents = FD_READ | FD_WRITE;
312SocketBaseImpl::connect(
const SocketAddress& addr)
324 m_sockfd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
328 Format(
"Failed to create a socket: %1",
329 System::lastErrorMsg(
true)).c_str());
333 WSANETWORKEVENTS networkEvents;
336 if(::WSAEventSelect(m_sockfd, m_event, FD_CONNECT) != 0)
339 Format(
"WSAEventSelect Failed: %1",
340 System::lastErrorMsg(
true)).c_str());
343 if (::connect(m_sockfd, addr.getNativeForm(), addr.getNativeFormSize())
346 int lastError = ::WSAGetLastError();
347 if (lastError != WSAEWOULDBLOCK && lastError != WSAEINPROGRESS)
349 _closeSocket(m_sockfd);
351 Format(
"Failed to connect to: %1: %2(%3)", addr.toString(),
352 lastError, System::lastErrorMsg(
true)).c_str());
355 TimeoutTimer timer(m_connectTimeout);
356 int tmoutval = timer.asDWORDMs();
362 if ((cc = waitForEvent(m_event, tmoutval)) < 1)
364 _closeSocket(m_sockfd);
369 "Sockets have been shutdown");
372 Format(
"Win32SocketBaseImpl connection"
373 " timed out. Timeout val = %1",
377 "connect() wait failed: %1(%2)",
379 System::lastErrorMsg(
true)).c_str());
384 if (::WSAEnumNetworkEvents(m_sockfd, m_event, &networkEvents)
387 _closeSocket(m_sockfd);
389 Format(
"SocketBaseImpl::connect()"
390 " failed getting network events: %1(%2)",
392 System::lastErrorMsg(
true)).c_str());
396 if (networkEvents.lNetworkEvents & FD_CONNECT)
399 if (networkEvents.iErrorCode[FD_CONNECT_BIT])
401 ::WSASetLastError(networkEvents.iErrorCode[FD_CONNECT_BIT]);
402 _closeSocket(m_sockfd);
404 Format(
"SocketBaseImpl::connect() failed: %1(%2)",
406 System::lastErrorMsg(
true)).c_str());
414 if(::WSAEventSelect(m_sockfd, m_event, 0) != 0)
416 _closeSocket(m_sockfd);
418 Format(
"Resetting socket with WSAEventSelect Failed: %1",
419 System::lastErrorMsg(
true)).c_str());
422 ::ioctlsocket(m_sockfd, FIONBIO, &ioctlarg);
424 m_isConnected =
true;
426 m_peerAddress = addr;
435SocketBaseImpl::disconnect()
439 m_in.clear(ios::eofbit);
443 m_out.clear(ios::eofbit);
447 m_inout.clear(ios::eofbit);
451 _closeSocket(m_sockfd);
452 m_isConnected =
false;
457SocketBaseImpl::fillInetAddrParms()
461 ::memset(&addr, 0,
sizeof(addr));
463 bool gotAddr =
false;
468 if (::getsockname(m_sockfd,
469 reinterpret_cast<struct sockaddr*
>(&addr), &len) != SOCKET_ERROR)
471 m_localAddress.assignFromNativeForm(&addr, len);
473 else if (getAddrFromIface(addr) == 0)
476 m_localAddress.assignFromNativeForm(&addr, len);
480 if (::getpeername(m_sockfd,
reinterpret_cast<struct sockaddr*
>(&addr),
481 &len) != SOCKET_ERROR)
483 m_peerAddress.assignFromNativeForm(&addr, len);
486 else if (getAddrFromIface(addr) == 0)
488 m_localAddress.assignFromNativeForm(&addr, len);
495SocketBaseImpl::write(
const void* dataOut,
int dataOutLen, ErrorAction errorAsException)
498 bool isError =
false;
501 isError = waitForOutput(m_sendTimeout);
508 rc = writeAux(dataOut, dataOutLen);
509 if (!m_traceFileOut.empty() && rc > 0)
512 ofstream traceFile(m_traceFileOut.c_str(), std::ios::app);
515 BLOCXX_THROW(IOException,
"Failed opening socket dump file");
517 if (!traceFile.write(
static_cast<const char*
>(dataOut), rc))
519 BLOCXX_THROW(IOException,
"Failed writing to socket dump");
522 ofstream comboTraceFile(String(m_traceFileOut +
"Combo").c_str(), std::ios::app);
525 BLOCXX_THROW(IOException,
"Failed opening socket dump file");
527 comboTraceFile <<
"\n--->Out " << rc <<
" bytes<---\n";
528 if (!comboTraceFile.write(
static_cast<const char*
>(dataOut), rc))
530 BLOCXX_THROW(IOException,
"Failed writing to socket dump");
539 if (rc < 0 && errorAsException)
547SocketBaseImpl::read(
void* dataIn,
int dataInLen, ErrorAction errorAsException)
550 bool isError =
false;
553 isError = waitForInput(m_recvTimeout);
560 rc = readAux(dataIn, dataInLen);
561 if (!m_traceFileIn.empty() && rc > 0)
564 ofstream traceFile(m_traceFileIn.c_str(), std::ios::app);
569 if (!traceFile.write(
reinterpret_cast<const char*
>(dataIn), rc))
571 BLOCXX_THROW(IOException,
"Failed writing to socket dump");
574 ofstream comboTraceFile(String(m_traceFileOut +
"Combo").c_str(), std::ios::app);
577 BLOCXX_THROW(IOException,
"Failed opening socket dump file");
579 comboTraceFile <<
"\n--->In " << rc <<
" bytes<---\n";
580 if (!comboTraceFile.write(
reinterpret_cast<const char*
>(dataIn), rc))
582 BLOCXX_THROW(IOException,
"Failed writing to socket dump");
593 if (errorAsException)
600SocketBaseImpl::waitForInput(
const Timeout& timeOutSecs)
602 int rval = SocketUtils::waitForIO(m_sockfd, m_event, timeOutSecs, FD_READ);
605 m_recvTimeoutExprd =
true;
609 m_recvTimeoutExprd =
false;
615SocketBaseImpl::waitForOutput(
const Timeout& timeOutSecs)
617 return SocketUtils::waitForIO(m_sockfd, m_event, timeOutSecs,
622SocketBaseImpl::getInputStream()
628SocketBaseImpl::getOutputStream()
634SocketBaseImpl::getIOStream()
641SocketBaseImpl::setDumpFiles(
const String& in,
const String& out)
643 m_traceFileOut = out;
#define BLOCXX_ASSERT(CON)
BLOCXX_ASSERT works similar to the assert() macro, but instead of calling abort(),...
#define BLOCXX_THROW(exType, msg)
Throw an exception using FILE and LINE.
static String m_traceFileOut
static String m_traceFileIn
static ShutDownMechanism_t getShutDownMechanism()
sockaddr_in InetSocketAddress_t