001:
002:
003:
004:
005:
006:
007:
008:
009:
010:
011:
012:
013:
014:
015:
016:
017:
018:
019:
020:
021:
022:
023:
024:
025:
026:
027:
028:
029:
030:
031:
032:
033:
034:
035:
036:
037:
038:
039:
040:
041:
042:
043:
044:
045:
046:
047:
048:
049:
050:
051:
052:
053:
054:
055:
056:
057:
058:
059:
060:
061:
062:
063:
064:
065:
066:
067:
068:
069:
070:
071:
072:
073:
074:
075:
076:
077:
078:
079:
080:
081:
082:
083:
084:
085:
086:
087:
088:
089:
090:
091:
092:
093:
094:
095:
096:
097:
098:
099:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527:
528:
529:
530:
531:
532:
533:
534:
535:
536:
537:
538:
539:
540:
541:
542:
543:
544:
545:
546:
547:
548:
549:
550:
551:
552:
553:
554:
555:
556:
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588:
589:
590:
591:
592:
593:
594:
595:
596:
597:
598:
599:
600:
601:
602:
603:
604:
605:
606:
607:
608:
609:
610:
611:
612:
613:
614:
615:
616:
617:
618:
619:
620:
621:
622:
623:
624:
625:
626:
627:
628:
629:
630:
631:























































































































































































































































































































































































































































































































































































































































/*
* Copyright (c), Zeriph Enterprises
* All rights reserved.
*
* Contributor(s):
* Zechariah Perez, omni (at) zeriph (dot) com
*
* THIS SOFTWARE IS PROVIDED BY ZERIPH AND CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL ZERIPH AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "omni/defs.hpp"
#include <sstream>
#if defined(OMNI_OS_WIN)
    #include <io.h>
    #include <winsock2.h>
    #include <malloc.h>
    #include <windows.h>
#else
    #include <unistd.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <signal.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include "omni/omni.hpp"
#include "omni/socket.hpp"
#include "omni/net.hpp"
#include "omni/system.hpp"
#include "omni/exceptions.hpp"
#include "omni/debug.hpp"

omni::net::socket::socket() :
    OMNI_INHERIT_OBJECT_DEF_MACRO
    blocking(0),
    dontFragment(0),
    enableBroadcast(0),
    exclusiveAddressUse(0),
    lingerstate(),
    multicastLoopback(0),
    nodelay(0),
    receiveBufferSize(0),
    receiveTimeout(0),
    sendBufferSize(0),
    sendTimeout(0),
    ttl(0),
    useOnlyOverlappedIO(0),
    datareceived(),
    m_AddressFamily(omni::net::address_family::UNKNOWN),
    m_Available(0),
    m_IsConnected(0),
    m_IsBound(0),
    m_IsShutdown(0),
    m_Handle(0),
    m_LocalEndPoint(""),
    m_ProtocolType(omni::net::protocol_type::UNKNOWN),
    m_RemoteEndPoint(""),
    m_SocketType(omni::net::socket_type::UNKNOWN)
{
    this->p_Initialize(
        omni::net::address_family::UNKNOWN,
        omni::net::socket_type::UNKNOWN,
        omni::net::protocol_type::UNKNOWN
    );
}

omni::net::socket::socket(const omni::net::socket &cp) :
    OMNI_INHERIT_OBJECT_CPY_MACRO
    blocking(cp.blocking),
    dontFragment(cp.dontFragment),
    enableBroadcast(cp.enableBroadcast),
    exclusiveAddressUse(cp.exclusiveAddressUse),
    lingerstate(cp.lingerstate),
    multicastLoopback(cp.multicastLoopback),
    nodelay(cp.nodelay),
    receiveBufferSize(cp.receiveBufferSize),
    receiveTimeout(cp.receiveTimeout),
    sendBufferSize(cp.sendBufferSize),
    sendTimeout(cp.sendTimeout),
    ttl(cp.ttl),
    useOnlyOverlappedIO(cp.useOnlyOverlappedIO),
    datareceived(cp.datareceived),
    m_AddressFamily(omni::net::address_family::UNKNOWN),
    m_Available(0),
    m_IsConnected(0),
    m_IsBound(0),
    m_IsShutdown(0),
    m_Handle(0),
    m_LocalEndPoint(""),
    m_ProtocolType(omni::net::protocol_type::UNKNOWN),
    m_RemoteEndPoint(""),
    m_SocketType(omni::net::socket_type::UNKNOWN)
{
    this->p_Initialize(
        omni::net::address_family::UNKNOWN,
        omni::net::socket_type::UNKNOWN,
        omni::net::protocol_type::UNKNOWN
    );
    this->m_AddressFamily = cp.addressFamily();
    this->m_Available = cp.available();
    this->m_IsConnected = cp.connected();
    this->m_IsBound = cp.is_bound();
    this->m_IsShutdown = cp.is_shut();
    this->m_Handle = cp.handle();
    this->m_LocalEndPoint = cp.localEndPoint();
    this->m_ProtocolType = cp.protocolType();
    this->m_RemoteEndPoint = cp.remoteEndPoint();
    this->m_SocketType = cp.socketType();
}

omni::net::socket::socket(
    omni::net::address_family::enum_t addressFamily,
    omni::net::socket_type::enum_t socketType,
    omni::net::protocol_type::enum_t protocolType) :
    OMNI_INHERIT_OBJECT_DEF_MACRO
    blocking(0),
    dontFragment(0),
    enableBroadcast(0),
    exclusiveAddressUse(0),
    lingerstate(),
    multicastLoopback(0),
    nodelay(0),
    receiveBufferSize(0),
    receiveTimeout(0),
    sendBufferSize(0),
    sendTimeout(0),
    ttl(0),
    useOnlyOverlappedIO(0),
    datareceived(),
    m_AddressFamily(addressFamily),
    m_Available(0),
    m_IsConnected(0),
    m_IsBound(0),
    m_IsShutdown(0),
    m_Handle(0),
    m_LocalEndPoint(""),
    m_ProtocolType(protocolType),
    m_RemoteEndPoint(""),
    m_SocketType(socketType)
{
    this->p_Initialize(addressFamily, socketType, protocolType);
}

omni::net::socket::~socket()
{
    this->dispose();
}

omni::net::address_family::enum_t omni::net::socket::addressFamily() const
{
    return this->m_AddressFamily;
}

int omni::net::socket::available() const
{
    return this->m_Available;
}

bool omni::net::socket::connected() const
{
    return this->m_IsConnected;
}

unsigned int omni::net::socket::handle() const
{
    return this->m_Handle;
}

void omni::net::socket::p_Initialize(
    omni::net::address_family::enum_t addressFamily,
    omni::net::socket_type::enum_t socketType,
    omni::net::protocol_type::enum_t protocolType
                                    )
{
    #if defined(OMNI_SHOW_DEBUG_ERR)
        dbga << "initializing" << std::endl;
    #endif
    // DEV_NOTE: Normally we would use the initialization list, but since we have actual functions and API calls to make
    // it's best to do the initialization in an initialize function
    this->m_Handle = -1;
    #if defined(OMNI_OS_WIN) // Microsoft set needed for sockets
        #if defined(OMNI_SHOW_DEBUG_ERR)
            dbga << "Calling WSAStartup" << std::endl;
        #endif
        WSADATA WSStartData;
        if ((WSAStartup(MAKEWORD(1,1), &WSStartData)) != 0) {
            #if defined(OMNI_SHOW_DEBUG_ERR)
                dbgerra << "Could not create omni::net::socket object (WSAStartup failed)" << std::endl;
            #endif
            #if !defined(OMNI_NO_THROW)
                throw omni::exceptions::net::wsa_failed();
            #endif
        }
    #endif
    int af = static_cast<int>(addressFamily);
    int st = static_cast<int>(socketType);
    int pt = static_cast<int>(protocolType);
    if ((this->m_Handle = ::socket(af, st, pt)) == -1) {
        #if defined(OMNI_SHOW_DEBUG_ERR)
            dbgerra << "Could not create socket object (socket() failed)" << std::endl;
        #endif
        #if !defined(OMNI_NO_THROW)
            throw omni::exceptions::net::socket_create_failed();
        #endif
    }
    this->m_AddressFamily = addressFamily;
    this->m_ProtocolType = protocolType;
    this->m_SocketType = socketType;
    this->m_Available = -1;
    this->m_IsConnected = false;
    this->m_IsBound = false;
    this->m_IsShutdown = false;
    this->m_LocalEndPoint = "";
    this->m_RemoteEndPoint = "";
    this->sendBufferSize = 0;
    this->sendTimeout = 0;
    this->ttl = 255;
    this->useOnlyOverlappedIO = false;
    this->receiveBufferSize = 65536;
    this->receiveTimeout = 1000;
    this->multicastLoopback = false;
    this->nodelay = true;
    this->dontFragment = false;
    this->enableBroadcast = false;
    this->exclusiveAddressUse = false;
}

bool omni::net::socket::is_bound() const
{
    return this->m_IsBound;
}

bool omni::net::socket::is_shut() const
{
    return this->m_IsShutdown;
}

const char *omni::net::socket::localEndPoint() const
{
    // TODO: Finish
    return this->m_LocalEndPoint;
}

omni::net::protocol_type::enum_t omni::net::socket::protocolType() const
{
    return this->m_ProtocolType;
}

const char *omni::net::socket::remoteEndPoint() const
{
    // TODO: Finish
    return this->m_RemoteEndPoint;
}

omni::net::socket_type::enum_t omni::net::socket::socketType() const
{
    return this->m_SocketType;
}

omni::net::socket &omni::net::socket::accept()
{
    // TODO: Finish
    return *this;
}

omni::net::socket &omni::net::socket::bind(std::string localIP)
{
    // TODO: Finish
    OMNI_UNUSED(localIP);
    return *this;
}

bool omni::net::socket::p_CloseSocket(int timeout, bool shutdown)
{
    if (this->m_Handle == -1) {
        #if defined(OMNI_SHOW_DEBUG_ERR)
            dbga << "The handle is invalid" << std::endl;
        #endif
        return false;
    }
    if (timeout > 0) {
        // TODO: setsockopt needs to set a LINGER struct so that it's timeout val = timeout
        //setsockopt(m_Handle,
        /*int setsockopt(
            SOCKET s,
            int level,
            int optname,
            const char *optval,
            int optlen
        );*/
    }
    if (shutdown && !this->shutdown(omni::net::socket_shutdown::BOTH)) {
        #if defined(OMNI_SHOW_DEBUG_ERR)
            int ec = omni::system::getLastError();
            dbga << "Could not shutdown the socket: " << ec << " - " << omni::system::getErrorString(ec) << std::endl;
        #endif
    }
    if (!this->m_IsConnected) {
        #if defined(OMNI_SHOW_DEBUG_ERR)
            dbga << "The socket has already been disconnected, no need to close" << std::endl;
        #endif
        return true;
    }
    #if defined(OMNI_SHOW_DEBUG_ERR)
        dbga << "Closing the socket" << std::endl;
    #endif
    int ret = -1;
    #if defined(OMNI_OS_WIN)
        ret = closesocket(this->m_Handle);
        if (ret == 0) { WSACleanup(); }
    #else
        ret = close(this->m_Handle);
    #endif
    #if defined(OMNI_SHOW_DEBUG_ERR)
        if (ret != 0) {
            int ec = omni::system::getLastError();
            dbga << "There was an error closing the socket: return value = " << ret << ", error = " << ec << " - " << omni::system::getErrorString(ec) << std::endl;
        }
    #endif
    this->m_IsConnected = !(ret == 0);
    return this->m_IsConnected;
}

bool omni::net::socket::close()
{
    return this->close(1000);
}

bool omni::net::socket::close(int timeout)
{
    return this->p_CloseSocket(timeout, true);
}

bool omni::net::socket::connect(std::string host, int port)
{
    if (this->m_Handle == -1) {
        #if defined(OMNI_SHOW_DEBUG_ERR)
            dbga << "The handle is invalid" << std::endl;
        #endif
        return false;
    }
    struct sockaddr_in Client;
    memset(&Client, 0, (sizeof(Client))); // recv
    Client.sin_family = static_cast<int>(this->m_AddressFamily);
    Client.sin_port = htons(port);
    Client.sin_addr.s_addr = inet_addr(host.c_str());
    #if defined(OMNI_SHOW_DEBUG_ERR)
        dbga << "Attempting to connect the socket to " << host << ":" << port << std::endl;
    #endif
    this->m_IsConnected = ((::connect(this->m_Handle, (reinterpret_cast<struct sockaddr*>(&Client)), sizeof(Client))) == 0);
    this->m_IsShutdown = !this->m_IsConnected;
    return this->m_IsConnected;
}

bool omni::net::socket::disconnect(bool reuseSocket)
{
    return this->p_CloseSocket(0, reuseSocket);
}

void omni::net::socket::dispose()
{
    if (this->m_IsConnected) { this->close(0); }
}

omni::net::socket *omni::net::socket::duplicateAndClose()
{
    omni::net::socket *Copy = new socket(*this);
    this->close();
    return Copy;
    // TODO: Finish .. Socket *Copy = new socket(*this);
    //                 this->Close();
    //                 return Copy;
    return (new omni::net::socket());
}

char *omni::net::socket::getSocketOption(
    omni::net::socket_option_level::enum_t optionLevel,
    omni::net::socket_option_name::enum_t optionName,
    int optionLength) const
{
    // TODO: Finish
    OMNI_UNUSED(optionLevel);
    OMNI_UNUSED(optionName);
    OMNI_UNUSED(optionLength);
    return 0;
}

int omni::net::socket::iocontrol(int ioControlCode, char *optionInValue, char *optionOutValue)
{
    // TODO: Finish
    OMNI_UNUSED(ioControlCode);
    OMNI_UNUSED(optionInValue);
    OMNI_UNUSED(optionOutValue);
    return 0;
}

omni::net::socket &omni::net::socket::listen(int backlog)
{
    // TODO: Finish
    OMNI_UNUSED(backlog);
    return *this;
}

bool omni::net::socket::poll(int microSeconds, omni::net::select_mode::enum_t mode)
{
    // TODO: Finish
    OMNI_UNUSED(microSeconds);
    OMNI_UNUSED(mode);
    return 0;
}

int omni::net::socket::receive(char *buffer, int size)
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(size);
    return 0;
}

int omni::net::socket::receive(char *buffer, int size, omni::net::socket_flags::enum_t socketFlags)
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    return 0;
}

int omni::net::socket::receive(char *buffer, int offset, int size, omni::net::socket_flags::enum_t socketFlags)
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(offset);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    return 0;
}

int omni::net::socket::receive(
    char *buffer,
    int offset,
    int size,
    omni::net::socket_flags::enum_t socketFlags,
    omni::net::socket_error::enum_t &errorCode
                            )
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(offset);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    OMNI_UNUSED(errorCode);
    return 0;
}

int omni::net::socket::receiveFrom(
    char *buffer,
    int size,
    omni::net::socket_flags::enum_t socketFlags,
    const char *remoteIP
                                )
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    OMNI_UNUSED(remoteIP);
    return 0;
}

int omni::net::socket::receiveFrom(
    char *buffer,
    int offset,
    int size,
    omni::net::socket_flags::enum_t socketFlags,
    const char *remoteIP
                                )
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(offset);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    OMNI_UNUSED(remoteIP);
    return 0;
}

int omni::net::socket::send(const char *buffer, int size, omni::net::socket_flags::enum_t socketFlags)
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    return 0;
}

int omni::net::socket::send(const char *buffer, int offset, int size, omni::net::socket_flags::enum_t socketFlags)
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(offset);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    return 0;
}

int omni::net::socket::send(
    const char *buffer,
    int offset,
    int size,
    omni::net::socket_flags::enum_t socketFlags,
    omni::net::socket_error::enum_t &errorCode
                            )
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(offset);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    OMNI_UNUSED(errorCode);
    return 0;
}

int omni::net::socket::sendto(const char *buffer, int size, omni::net::socket_flags::enum_t socketFlags, const char *remoteIP)
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    OMNI_UNUSED(remoteIP);
    return 0;
}

int omni::net::socket::sendto(const char *buffer, int offset, int size, omni::net::socket_flags::enum_t socketFlags, const char *remoteIP)
{
    // TODO: Finish
    OMNI_UNUSED(buffer);
    OMNI_UNUSED(offset);
    OMNI_UNUSED(size);
    OMNI_UNUSED(socketFlags);
    OMNI_UNUSED(remoteIP);
    return 0;
}

omni::net::socket &omni::net::socket::setSocketOption(
    omni::net::socket_option_level::enum_t optionLevel,
    omni::net::socket_option_name::enum_t optionName,
    int optionValue
                                    )
{
    // TODO: Finish
    OMNI_UNUSED(optionLevel);
    OMNI_UNUSED(optionName);
    OMNI_UNUSED(optionValue);
    return *this;
}

bool omni::net::socket::shutdown(omni::net::socket_shutdown::enum_t how)
{
    if (this->m_Handle == -1) {
        #if defined(OMNI_SHOW_DEBUG_ERR)
            dbga << "The handle is invalid" << std::endl;
        #endif
        return false;
    }
    if (this->m_IsShutdown) {
        #if defined(OMNI_SHOW_DEBUG_ERR)
            dbga << "The socket is shutdown, nothing to do" << std::endl;
        #endif
        return true;
    }
    #if defined(OMNI_SHOW_DEBUG_ERR)
        dbga << "Shutting down the socket" << std::endl;
    #endif
    this->m_IsShutdown = (::shutdown(this->m_Handle, static_cast<int>(how)) == 0);
    if (!this->m_IsShutdown) { // Stop sending/receiving data
        #if defined(OMNI_SHOW_DEBUG_ERR)
            int ErrorCode = omni::system::getLastError();
            dbga << "Socket shutdown failed: " << ErrorCode << " - " << omni::system::getErrorString(ErrorCode) << std::endl;
        #endif
    }
    return this->m_IsShutdown;
}

const std::string omni::net::socket::tostring() const
{
    // TODO: return this->IP
    return "0.0.0.0";
}

omni::net::socket &omni::net::socket::operator= (const omni::net::socket &other)
{
    this->close();
    this->blocking = other.blocking;
    this->dontFragment = other.dontFragment;
    this->enableBroadcast = other.enableBroadcast;
    this->exclusiveAddressUse = other.exclusiveAddressUse;
    this->lingerstate = other.lingerstate,
    this->multicastLoopback = other.multicastLoopback;
    this->nodelay = other.nodelay;
    this->receiveBufferSize = other.receiveBufferSize;
    this->receiveTimeout = other.receiveTimeout;
    this->sendBufferSize = other.sendBufferSize;
    this->sendTimeout = other.sendTimeout;
    this->ttl = other.ttl;
    this->useOnlyOverlappedIO = other.useOnlyOverlappedIO;
    this->datareceived = other.datareceived;    
    this->m_AddressFamily = other.addressFamily();
    this->m_Available = other.available();
    this->m_IsConnected = other.connected();
    this->m_IsBound = other.is_bound();
    this->m_IsShutdown = other.is_shut();
    this->m_Handle = other.handle();
    this->m_LocalEndPoint = other.localEndPoint();
    this->m_ProtocolType = other.protocolType();
    this->m_RemoteEndPoint = other.remoteEndPoint();
    this->m_SocketType = other.socketType();
    return *this;
}