genesis-3d_engine/Engine/foundation/net/win360/win360socket.h
zhongdaohuan 6e8fbca745 genesis-3d engine version 1.3.
match the genesis editor version 1.3.0.653.
2014-05-05 14:50:33 +08:00

415 lines
12 KiB
Objective-C

#pragma once
/****************************************************************************
Copyright (c) 2007, Radon Labs GmbH
Copyright (c) 2011-2013,WebJet Business Division,CYOU
http://www.genesis-3d.com.cn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
//------------------------------------------------------------------------------
/**
@class Win360::Win360Socket
NOTE: Socket network communication on the Xbox360 is only provided
for debugging and development purposes. For actual multiplayer and
Xbox Live related stuff, use the Xbox-specific add-on modules!
A lowlevel socket wrapper class. This class is primarily a
platform abstraction class, not an "end-user-class". Usually a Nebula3
application doesn't use this class directly but instead uses the higher
level classes like TcpServer, TclClient, etc...
(C) 2007 Radon Labs GmbH
*/
#include "core/refcounted.h"
#include "net/socket/ipaddress.h"
namespace Net
{
class Socket;
}
//------------------------------------------------------------------------------
namespace Win360
{
class Win360Socket : public Core::RefCounted
{
__DeclareClass(Win360Socket);
public:
/// protocol types
enum Protocol
{
TCP, // a reliable TCP connection
UDP, // unreliable UDP connection
};
// return values
enum Result
{
Error = 0, // an error occured, call GetErrorCode() or GetErrorString() for more info
Success, // everything ok
WouldBlock, // operation on non-blocking socket is not complete
Closed, // connection has been gracefully closed
};
/// error codes
enum ErrorCode
{
ErrorNone, // no error occured
ErrorUnknown, // an "unknown" error occured
ErrorInterrupted, // WSAEINTR
ErrorPermissionDenied, // WSAEACCESS
ErrorBadAddress, // WSAEFAULT
ErrorInvalidArgument, // WSAEINVAL
ErrorTooManyOpenFiles, // WSAEMFILE
ErrorWouldBlock, // WSAEWOULDBLOCK
ErrorInProgress, // WSAEINPROGRESS
ErrorAlreadyInProgress, // WSAEALREADY
ErrorNotASocket, // WSAENOTSOCK
ErrorDestAddrRequired, // WSAEDESTADDRREQ
ErrorMsgTooLong, // WSAEMSGSIZE
ErrorInvalidProtocol, // WSAEPROTOTYPE
ErrorBadProtocolOption, // WSAENOPROTOOPT
ErrorProtocolNotSupported, // WSEAPROTONOSUPPORT
ErrorSocketTypeNotSupported, // WSAESOCKTNOSUPPORT
ErrorOperationNotSupported, // WSAEOPNOTSUPP
ErrorProtFamilyNotSupported, // WSAEPFNOSUPPORT
ErrorAddrFamilyNotSupported, // WSAEAFNOSUPPORT
ErrorAddrInUse, // WSAEADDRINUSE
ErrorAddrNotAvailable, // WSAEADDRNOTAVAIL
ErrorNetDown, // WSAENETDOWN
ErrorNetUnreachable, // WSAENETUNREACH
ErrorNetReset, // WSAENETRESET
ErrorConnectionAborted, // WSAECONNABORTED
ErrorConnectionReset, // WSAECONNRESET
ErrorNoBufferSpace, // WSAENOBUFS
ErrorIsConnected, // WSAEISCONN
ErrorNotConnected, // WSAENOTCONNECTED
ErrorIsShutdown, // WSAESHUTDOWN
ErrorIsTimedOut, // WSAETIMEDOUT
ErrorConnectionRefused, // WSAECONNREFUSED
ErrorHostDown, // WSAEHOSTDOWN
ErrorHostUnreachable, // WSAEHOSTUNREACH
ErrorTooManyProcesses, // WSAEPROCLIM
ErrorSystemNotReady, // WSAESYSNOTREADY
ErrorVersionNotSupported, // WSAEVERNOTSUPPORTED
ErrorNotInitialized, // WSAENOTINITIALISED
ErrorDisconnecting, // WSAEDISCONN
ErrorTypeNotFound, // WSAETYPE_NOT_FOUND
ErrorHostNotFound, // WSAEHOST_NOT_FOUND
ErrorTryAgain, // WSAETRY_AGAIN
ErrorNoRecovery, // WSAENO_RECOVERY
ErrorNoData, // WSAENO_DATA
};
/// constructor
Win360Socket();
/// destructor
virtual ~Win360Socket();
/// static initializer method (called by SysFunc::Setup())
static void InitNetwork();
/// is network initialized
static bool IsNetworkInitialized();
/// open the socket
bool Open(Protocol p);
/// close the socket
void Close();
/// return true if the socket is open
bool IsOpen() const;
/// get the last error code
ErrorCode GetErrorCode() const;
/// get the last error string
Util::String GetErrorString() const;
/// set internet address of socket
void SetAddress(const Net::IpAddress& a);
/// get internet address of socket
const Net::IpAddress& GetAddress() const;
/// set the broadcast flag (SO_BROADCAST)
void SetBroadcast(bool b);
/// get the broadcast flag
bool GetBroadcast();
/// set the keepalive flag (SO_KEEPALIVE)
void SetKeepAlive(bool b);
/// get the keepalive flag
bool GetKeepAlive();
/// set reuseaddr flag (SO_REUSEADDR)
void SetReUseAddr(bool b);
/// get reuseaddr flag
bool GetReUseAddr();
/// set nodelay flag (TCP_NODELAY)
void SetNoDelay(bool b);
/// get nodelay flag
bool GetNoDelay();
/// set receive buffer size
void SetRecvBufSize(SizeT s);
/// get receive buffer size
SizeT GetRecvBufSize();
/// set send buffer size
void SetSendBufSize(SizeT s);
/// get send buffer size
SizeT GetSendBufSize();
/// set blocking mode (FIONBIO)
void SetBlocking(bool b);
/// get blocking mode
bool GetBlocking() const;
/// get the maximum message size that can be sent atomically
SizeT GetMaxMsgSize();
/// bind socket to ip address
bool Bind();
/// return true if the socket is bound to an address
bool IsBound() const;
/// listen for incoming connections (for server sockets)
bool Listen();
/// accept incoming connection, return a new socket (for server sockets)
bool Accept(GPtr<Net::Socket>& outSocket);
/// connect to the sockets address (for client sockets)
Result Connect();
/// test if the socket is currently connected
bool IsConnected();
/// send raw data into the socket
Result Send(const void* buf, SizeT numBytes, SizeT& bytesSent);
/// return true if recv data is available at the socket
bool HasRecvData();
/// receive raw data from the socket
Result Recv(void* buf, SizeT bufSize, SizeT& bytesReceived);
/// send raw data to address for connectionless sockets
Result SendTo(const void* buf, SizeT numBytes, uint addr, ushort port, SizeT& bytesSent);
/// receive raw data from address for connectionless sockets
Result RecvFrom(void* buf, SizeT bufSize, uint addr, ushort port, SizeT& bytesReceived);
private:
friend class Win360IpAddress;
/// open with an existing socket (called by Accept())
void OpenWithExistingSocket(SOCKET s);
/// clear the last error code
void ClearError();
/// set error code to WSAGetLastError();
void SetToLastWSAError();
/// set WSA error code
void SetWSAError(int wsaError);
/// convert a WSA error code to internal error code
static ErrorCode WSAErrorToErrorCode(int wsaError);
/// convert error code to human readable string
static Util::String ErrorAsString(ErrorCode err);
/// convert WSA error code directly to string
static Util::String WSAErrorToString(int wsaError);
/// set a bool socket option
void SetBoolOption(int optName, bool val);
/// get a bool socket option
bool GetBoolOption(int optName);
/// set an integer socket option
void SetIntOption(int optName, int val);
/// get an integer socket option
int GetIntOption(int optName);
static bool NetworkInitialized;
ErrorCode error;
SOCKET sock;
Net::IpAddress addr;
bool isBlocking;
bool isBound;
};
//------------------------------------------------------------------------------
/**
*/
inline bool
Win360Socket::IsOpen() const
{
return (0 != this->sock);
}
//------------------------------------------------------------------------------
/**
*/
inline bool
Win360Socket::IsBound() const
{
return this->isBound;
}
//------------------------------------------------------------------------------
/**
Set internet address of socket.
*/
inline void
Win360Socket::SetAddress(const Net::IpAddress& a)
{
this->addr = a;
}
//------------------------------------------------------------------------------
/**
Get internet address of socket.
*/
inline const Net::IpAddress&
Win360Socket::GetAddress() const
{
return this->addr;
}
//------------------------------------------------------------------------------
/**
*/
inline void
Win360Socket::SetBroadcast(bool b)
{
this->SetBoolOption(SO_BROADCAST, b);
}
//------------------------------------------------------------------------------
/**
*/
inline bool
Win360Socket::GetBroadcast()
{
return this->GetBoolOption(SO_BROADCAST);
}
//------------------------------------------------------------------------------
/**
*/
inline void
Win360Socket::SetKeepAlive(bool b)
{
// not supported on Xbox360
#if __WIN32__
this->SetBoolOption(SO_KEEPALIVE, b);
#endif
}
//------------------------------------------------------------------------------
/**
*/
inline bool
Win360Socket::GetKeepAlive()
{
#if __WIN32__
return this->GetBoolOption(SO_KEEPALIVE);
#else
// not supported on Xbox360
return false;
#endif
}
//------------------------------------------------------------------------------
/**
*/
inline void
Win360Socket::SetReUseAddr(bool b)
{
this->SetBoolOption(SO_REUSEADDR, b);
}
//------------------------------------------------------------------------------
/**
*/
inline bool
Win360Socket::GetReUseAddr()
{
return this->GetBoolOption(SO_REUSEADDR);
}
//------------------------------------------------------------------------------
/**
*/
inline void
Win360Socket::SetNoDelay(bool b)
{
this->SetBoolOption(TCP_NODELAY, b);
}
//------------------------------------------------------------------------------
/**
*/
inline bool
Win360Socket::GetNoDelay()
{
return this->GetBoolOption(TCP_NODELAY);
}
//------------------------------------------------------------------------------
/**
*/
inline void
Win360Socket::SetRecvBufSize(SizeT s)
{
this->SetIntOption(SO_RCVBUF, s);
}
//------------------------------------------------------------------------------
/**
*/
inline SizeT
Win360Socket::GetRecvBufSize()
{
return this->GetIntOption(SO_RCVBUF);
}
//------------------------------------------------------------------------------
/**
*/
inline void
Win360Socket::SetSendBufSize(SizeT s)
{
this->SetIntOption(SO_SNDBUF, s);
}
//------------------------------------------------------------------------------
/**
*/
inline SizeT
Win360Socket::GetSendBufSize()
{
return this->GetIntOption(SO_SNDBUF);
}
//------------------------------------------------------------------------------
/**
*/
inline SizeT
Win360Socket::GetMaxMsgSize()
{
#if __WIN32__
return 8192;
#else
// see Xbox360 API documentation
return 1264;
#endif
}
//------------------------------------------------------------------------------
/**
*/
inline bool
Win360Socket::GetBlocking() const
{
return this->isBlocking;
}
} // namespace Xbox360
//------------------------------------------------------------------------------