win_net.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,166 行 · 第 1/4 页
CPP
2,166 行
if (conn::is_cached((char *) host, &mHostIPAddr))
{
mHostIPValid = TRUE;
mDNSDone = TRUE;
mLastError = HXR_OK;
if (mCallBack)
{
mCallBack->Func(DNS_NOTIFICATION, TRUE);
}
return mLastError;
}
char* pTemp = strrchr(host, '.');
if (pTemp && atoi(pTemp + 1))
{ /* IP address. */
struct in_addr addr;
mHostIPValid = FALSE;
mHostIPAddr = 0;
mDNSDone = TRUE;
addr.s_addr = sockObj->HXinet_addr(host);
if ((UINT)addr.s_addr == (UINT)-1)
{
mLastError = HXR_DNR;
return mLastError;
}
mHostIPValid = TRUE;
mHostIPAddr = *(ULONG32 *) &addr;
conn::add_to_cache((char *) host, mHostIPAddr);
if (mCallBack)
{
mCallBack->Func(DNS_NOTIFICATION, TRUE);
}
return HXR_OK;
}
if (blocking)
{
struct in_addr addr;
mHostIPValid = FALSE;
mHostIPAddr = 0;
mDNSDone = TRUE;
struct hostent *h = sockObj->HXgethostbyname(host);
if (!h || !h->h_addr )
{
mLastError = HXR_DNR;
return mLastError;
}
memcpy(&addr, h->h_addr, sizeof(struct in_addr)); /* Flawfinder: ignore */
mHostIPValid = TRUE;
mHostIPAddr = *(ULONG32 *) &addr;
conn::add_to_cache((char *) host, mHostIPAddr);
if (mCallBack)
{
mCallBack->Func(DNS_NOTIFICATION, TRUE);
}
return( mLastError = HXR_OK);
}
else
{
if (m_pAsyncHost != host)
{
// Save the parameters, and tell ourselves we're starting up
HX_VECTOR_DELETE(m_pAsyncHost);
m_pAsyncHost = ::new_string(host);
}
if (!m_AsyncAddress)
{
m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
}
if (!m_AsyncAddress)
{
return (mLastError = HXR_OUTOFMEMORY);
}
// set the boolean variable that we are only doing async DNs and
// do not intend to connect
#ifndef WIN32_PLATFORM_PSPC
m_DNSOnly = TRUE;
m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , TRUE);
m_AsyncNotifier->DoAsyncDNS( this, m_pAsyncHost, m_AsyncAddress, MAXGETHOSTSTRUCT );
m_SocketState = CONN_DNS_INPROG;
#else
m_DNSOnly = FALSE;
#endif
return( mLastError = HXR_WOULD_BLOCK );
}
}
BOOL win_net::dns_ip_addr_found(BOOL * valid, ULONG32 *addr)
{
if (mDNSDone)
{
// reset DNS only flag...
m_DNSOnly = FALSE;
*valid = mHostIPValid;
*addr = mHostIPAddr;
return TRUE;
}
else
return FALSE;
}
BOOL win_net::set_receive_buf_size(int DesiredSize)
{
int s = get_sock();
if (s == INVALID_SOCKET)
{
mLastError = HXR_NET_SOCKET_INVALID;
return FALSE;
}
int RcvBufSize = 0;
int iSize = sizeof(RcvBufSize);
if (sockObj->HXgetsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&RcvBufSize,
&iSize))
{
RcvBufSize = 0;
}
if (RcvBufSize < DesiredSize)
{
RcvBufSize = DesiredSize;
if(sockObj->HXsetsockopt(s, SOL_SOCKET, SO_RCVBUF,
(char *)&RcvBufSize, sizeof(RcvBufSize)))
{
int code;
code = sockObj->HXWSAGetLastError();
return FALSE;
}
}
return TRUE;
}
/*
* reuse_addr/reuse_port has to be called before a sock binds. however,
* socket is not available until it binds as it is implemented. So, set a
* flag here and do the actual setsockopt right before a sock binds.
* Look in init_win().
*/
HX_RESULT
win_net::reuse_addr(BOOL enable)
{
m_bReuseAddr = enable;
return HXR_OK;
}
HX_RESULT
win_net::reuse_port(BOOL enable)
{
m_bReusePort = enable;
return HXR_OK;
}
HX_RESULT
win_net::get_host_name(char* name, int namelen)
{
HX_ASSERT(sockObj);
if (sockObj->HXgethostname(name, namelen) != 0)
{
return HXR_FAILED;
}
else
{
return HXR_OK;
}
}
HX_RESULT
win_net::get_host_by_name(char* name, REF(struct hostent*) h)
{
HX_ASSERT(sockObj);
h = sockObj->HXgethostbyname(name);
if (!h || !h->h_addr_list)
{
return HXR_DNR;
}
else
{
return HXR_OK;
}
}
HX_RESULT win_UDP::set_broadcast(BOOL enable)
{
int ret;
SOCKET s = get_sock();
if(s == INVALID_SOCKET)
{
return( mLastError = HXR_NET_SOCKET_INVALID );
}
ret = sockObj->HXsetsockopt( s, SOL_SOCKET, SO_BROADCAST, (char*)&enable, sizeof(UINT32) );
if(ret == -1)
ret = HXR_BIND;
return ret;
}
HX_RESULT
win_UDP::set_send_size(UINT32 send_size)
{
int s = get_sock();
int ret = 0;
again:
ret = sockObj->HXsetsockopt(s, SOL_SOCKET, SO_SNDBUF,
(char*)&send_size, sizeof(INT32));
if (ret < 0 && send_size > 8192)
{
send_size >>= 1;
goto again;
}
return ret;
}
HX_RESULT win_UDP::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform )
{
HX_RESULT ret;
if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
{
if(ret == HXR_BLOCK_CANCELED)
return ret;
mLastError = HXR_NET_CONNECT;
return mLastError;
}
return win_net::connect(host, port, blocking, ulPlatform );
}
HX_RESULT win_UDP::SetWindowHandle(ULONG32 handle)
{
m_hInst = (HINSTANCE)handle;
#ifndef WIN32_PLATFORM_PSPC
m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst ,TRUE);
m_AsyncNotifier->DoAsyncSelect( this );
#endif
return HXR_OK;
}
HX_RESULT win_UDP::connect(sockaddr_in * addr, UINT16 blocking)
{
HX_RESULT ret;
if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
{
if(ret == HXR_BLOCK_CANCELED)
return ret;
mLastError = HXR_NET_CONNECT;
return mLastError;
}
return win_net::connect(addr);
}
HX_RESULT win_TCP::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform )
{
HX_RESULT ret;
if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
{
if(ret == HXR_BLOCK_CANCELED)
return ret;
mLastError = HXR_NET_CONNECT;
return mLastError;
}
return win_net::connect(host, port, blocking, ulPlatform );
}
HX_RESULT win_TCP::connect(sockaddr_in * addr, UINT16 blocking)
{
HX_RESULT ret;
if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
{
if(ret == HXR_BLOCK_CANCELED)
return ret;
mLastError = HXR_NET_CONNECT;
return mLastError;
}
return win_net::connect(addr);
}
inline HX_RESULT win_UDP::listen(ULONG32 ulLocalAddr, UINT16 port,
UINT16 backlog, UINT16 blocking,
ULONG32 ulPlatform)
{
return HXR_INVALID_OPERATION;
}
inline HX_RESULT win_TCP::listen(ULONG32 ulLocalAddr, UINT16 port,
UINT16 backlog, UINT16 blocking,
ULONG32 ulPlatform)
{
HX_RESULT ret = HXR_NET_SOCKET_INVALID;
if ( get_sock() < 0 )
{
if ( ulLocalAddr == HX_INADDR_ANY )
ret = init(INADDR_ANY, port, blocking);
else
ret = init(ulLocalAddr, port, blocking);
}
if ( FAILED(ret) )
{
if(ret == HXR_BLOCK_CANCELED)
return ret;
mLastError = HXR_NET_SOCKET_INVALID;
return mLastError;
}
return win_net::listen(ulLocalAddr, port, backlog, blocking, ulPlatform);
}
HX_RESULT
win_UDP::set_multicast()
{
#ifdef NO_MULTICAST
return HXR_MULTICAST_UDP;
#else
INT32 ret;
sockaddr_in addr;
int addr_len = sizeof addr;
if (get_sock() == INVALID_SOCKET)
{
// Not connected
return( mLastError = HXR_NET_SOCKET_INVALID );
}
memset(&addr, 0, HX_SAFESIZE_T(addr_len));
ret = sockObj->HXgetsockname(get_sock(), (sockaddr*)&addr, &addr_len);
if (ret < 0)
{
return HXR_MULTICAST_UDP;
}
ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_MULTICAST_IF,
(char*) &addr.sin_addr.s_addr,
sizeof (addr.sin_addr.s_addr));
if (ret < 0)
{
return HXR_MULTICAST_UDP;
}
return HXR_OK;
#endif /* NO_MULTICAST */
}
HX_RESULT
win_UDP::set_multicast_ttl(unsigned char ttl)
{
#ifdef NO_MULTICAST
return HXR_MULTICAST_UDP;
#else
if (get_sock() == INVALID_SOCKET)
{
// Not connected
return( mLastError = HXR_NET_SOCKET_INVALID );
}
INT32 ret;
INT32 ttl_proxy = ttl;
ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_MULTICAST_TTL,
(char*) &ttl_proxy, sizeof (ttl_proxy));
if (ret < 0)
{
return HXR_MULTICAST_UDP;
}
return HXR_OK;
#endif /* ! NO_MULTICAST */
}
HX_RESULT win_UDP::join_multicast_group(ULONG32 addr, ULONG32 if_addr)
{
int ret;
ip_mreq multicast_group;
if (get_sock() == INVALID_SOCKET)
{
// Not connected
return( mLastError = HXR_NET_SOCKET_INVALID );
}
multicast_group.imr_multiaddr.s_addr = sockObj->HXhtonl(addr);
multicast_group.imr_interface.s_addr = sockObj->HXhtonl(if_addr);
ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multicast_group , sizeof (multicast_group) );
if (ret == -1)
{
int err;
err = sockObj->HXWSAGetLastError();
return HXR_MULTICAST_JOIN;
}
return HXR_OK;
}
HX_RESULT win_UDP::leave_multicast_group(ULONG32 addr, ULONG32 if_addr)
{
int ret;
ip_mreq multicast_group;
if (get_sock() == INVALID_SOCKET)
{
// Not connected
return( mLastError = HXR_NET_SOCKET_INVALID );
}
multicast_group.imr_multiaddr.s_addr = sockObj->HXhtonl(addr);
// multicast_group.imr_multiaddr.s_addr = sockObj->HXinet_addr("226.0.0.8");
multicast_group.imr_interface.s_addr = sockObj->HXhtonl(if_addr);
ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&multicast_group , sizeof (multicast_group) );
if (ret == -1)
{
return HXR_GENERAL_MULTICAST;
}
return HXR_OK;
}
HX_RESULT
win_UDP::set_multicast_if(ULONG32 ulInterface)
{
int ret;
int s = get_sock();
if(s == INVALID_SOCKET)
{
return( mLastError = HXR_NET_SOCKET_INVALID );
}
unsigned long addr = sockObj->HXhtonl(ulInterface);
ret = sockObj->HXsetsockopt(s, IPPROTO_IP, IP_MULTICAST_IF,
(char*)&addr, sizeof(addr));
if(ret == -1)
ret = HXR_GENERAL_MULTICAST;
return ret;
}
HX_RESULT
win_UDP::GetFromInfo(ULONG32& ulAddr, UINT16& nPort)
{
return HXR_OK;
}
WinsockManager::WinsockManager()
{
bInitialized = FALSE;
Initialize();
}
WinsockManager::~WinsockManager()
{
conn::close_drivers(NULL);
bInitialized = FALSE;
}
void
WinsockManager::Initialize()
{
bInitialized = FALSE;
HX_ASSERT(!sockObj);
if(!sockObj)
sockObj = new CHXSock;
if(conn::init_drivers(NULL) != HXR_OK)
return;
if(sockObj && sockObj->WinSockAvail() && sockObj->InitWinsock())
{
bInitialized = TRUE;
}
UINT8 nWinSockVersion = sockObj->HXGetVersion();
/*
* Check to see what platform we are on
*/
OSVERSIONINFO winver;
winver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
#ifndef WIN32_PLATFORM_PSPC
if(GetVersionEx(&winver))
{
if(nWinSockVersion == 2 &&
winver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS &&
winver.dwMinorVersion == 0)
{
/*
* Async lookup in Win 95 with WinSock2.0 installed returns the same handle for
* multiple requests. If there are multiple outstanding requests, there is
* no way to map the handle in the response to the outstansing request since
* all replies get mapped to one request. NT 4.0 returns different handles so
* name resolution works fine.
*
* We workaround this by queueing up the DNS requests.
*/
sockGlobals.m_bWinSock2Suck = TRUE;
}
}
#endif
}
BOOL
WinsockManager::IsInitialized()
{
return bInitialized && sockObj;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?