win_net.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,166 行 · 第 1/4 页
CPP
2,166 行
return bReadyToWrite;
}
void win_net::done (void)
{
#ifndef WIN32_PLATFORM_PSPC
m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , FALSE);
if (m_AsyncNotifier)
{
m_AsyncNotifier->CancelSelect( this );
}
#endif
m_SocketState = CONN_CLOSING;
if ((get_sock() != INVALID_SOCKET) && sockObj)
{
if (sockObj->HXclosesocket(get_sock()))
{
int code = 0;
code = sockObj->HXWSAGetLastError();
}
}
set_sock( INVALID_SOCKET );
m_SocketState = CONN_CLOSED;
mConnectionOpen = 0;
}
inline HX_RESULT win_net::listen(ULONG32 ulLocalAddr, UINT16 port,
UINT16 backlog, UINT16 blocking,
ULONG32 ulPlatform)
{
m_hInst = (HINSTANCE)ulPlatform;
// accept is polled
#ifndef WIN32_PLATFORM_PSPC
m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier(m_hInst ,TRUE);
m_AsyncNotifier->DoAsyncSelect((win_net*)this );
#endif
HX_RESULT ret = sockObj->HXlisten(get_sock(), backlog);
if ( SUCCEEDED(ret) )
{
m_SocketState = CONN_LISTENNING;
ret = HXR_OK;
}
else
{
ret = HXR_NET_SOCKET_INVALID;
}
return ret;
}
inline HX_RESULT win_net::blocking (void)
{
unsigned long nonblocking = 0;
return sockObj->HXioctlsocket(get_sock(), FIONBIO, &nonblocking);
}
inline HX_RESULT win_net::nonblocking (void)
{
unsigned long nonblocking = 1;
return sockObj->HXioctlsocket(get_sock(), FIONBIO, &nonblocking);
}
HX_RESULT win_net::connect_accept(ULONG32 ulPlatform, sockaddr_in addr)
{
m_hInst = (HINSTANCE)ulPlatform;
CurrentAddr = addr.sin_addr.s_addr;
// set up the new connection so it will use its own notifier.
// now we want to add this so it will recieve messages.
#ifndef WIN32_PLATFORM_PSPC
m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst, TRUE);
m_AsyncNotifier->DoAsyncSelect(this);
#endif
m_SocketState = CONN_OPEN;
mConnectionOpen = 1;
return HXR_OK;
}
CHXMapPtrToPtr win_net::zm_MapObjectsToWinsockTasks;
CHXMapPtrToPtr win_net::zm_WinsockTasksRefCounts;
int win_net::zm_LibRefCount = 0;
BOOL win_net::IsWinsockAvailable(void* pObject)
{
BOOL bWinSockInitedForTask = FALSE;
// First check to see that the drivers are loaded...
//
// NOTE: this doesn't include initializing Winsock for
// the object's task...
if(!OnlyOneOfThisInTheWholeProgram.IsInitialized())
{
OnlyOneOfThisInTheWholeProgram.Initialize();
}
if(OnlyOneOfThisInTheWholeProgram.IsInitialized())
{
zm_LibRefCount++;
// Make sure Winsock is initialized for the object's task...
// get current task.
#if defined( WIN32 )
void* ulTask = (void*)GetCurrentProcessId();
#else
void* ulTask = (void*)GetCurrentTask();
#endif
// add map of object (http or session) to task
zm_MapObjectsToWinsockTasks[pObject] = ulTask;
// bump up ref count for task
void* pVoid;
ULONG32 TaskRefCount = 0;
if (zm_WinsockTasksRefCounts.Lookup(ulTask,pVoid))
{
TaskRefCount = (ULONG32)pVoid;
}
TaskRefCount++;
bWinSockInitedForTask = TRUE;
HX_ASSERT_VALID_PTR(sockObj);
zm_WinsockTasksRefCounts[ulTask] = (void*)TaskRefCount;
}
return bWinSockInitedForTask;
}
BOOL win_net::ReleaseWinsockUsage(void* pObject)
{
// Only do any of this if we've first called IsWinsockAvailable()
if (zm_LibRefCount > 0)
{
// get previous task from map of object (http or session) to task
void* ulTask;
if (zm_MapObjectsToWinsockTasks.Lookup(pObject,ulTask))
{
zm_MapObjectsToWinsockTasks.RemoveKey(pObject);
// bump up ref count for task
void* pVoid;
ULONG32 TaskRefCount = 0;
if (zm_WinsockTasksRefCounts.Lookup(ulTask,pVoid))
{
TaskRefCount = (ULONG32)pVoid;
}
TaskRefCount--;
// if 0 then call WSACleanup
if (TaskRefCount == 0)
{
zm_WinsockTasksRefCounts.RemoveKey(ulTask);
}
}
// Decerement total ref count
zm_LibRefCount--;
}
return TRUE;
}
HX_RESULT win_net::read(void * buf, UINT16 *len)
{
int got;
static int breakpoint = 0;
assert( buf );
assert( len );
// This DEBUGOUTSTR is noisy.
#ifndef _DEMPSEY
DEBUGOUTSTR( "win_net::read()\r\n" );
#endif // !_DEMPSEY
if (get_sock() == INVALID_SOCKET || !callRaConnect)
{
// Not connected
return( mLastError = HXR_NET_SOCKET_INVALID );
}
// Is the TCP socket actually connected yet?
/* We want to read data even if we have received CloseNotification.
* This is because some unread data may be still be in the pipe
* - RA 10/01/1997
*/
if (m_SocketState != CONN_OPEN && m_SocketState != CONN_CLOSED)
{
// No
// We won't be able to write anything here, so clear this
// we'll return why we didn't write anything.
*len = 0;
switch( m_SocketState )
{
case CONN_DNS_INPROG:
case CONN_CONNECT_INPROG:
case CONN_CLOSING:
return( mLastError = HXR_WOULD_BLOCK );
case CONN_CLOSED:
return( mLastError = HXR_NET_SOCKET_INVALID );
case CONN_NO_CONN:
#ifndef WIN32_PLATFORM_PSPC
return( DoStartAsyncConn() );
#else
HX_ASSERT(0 && "No Async net");
return( HXR_NET_READ );
#endif
case CONN_DNS_FAILED:
return( mLastError = HXR_DNR );
case CONN_CONNECT_FAILED:
return( mLastError = HXR_NET_CONNECT );
default:
// HUH???
HX_ASSERT (FALSE);
return( mLastError = HXR_NET_READ );
};
}
else
{
// Now we can actually do the read
if (callRaConnect)
{
got = sockObj->HXrecv( get_sock(), (char *)buf, *len, 0 );
}
else
{
int fromlen;
struct sockaddr from;
fromlen = sizeof( from );
got = sockObj->HXrecvfrom( get_sock(), (char *)buf, *len, 0, &from, &fromlen );
if (got > 0) breakpoint++;
}
// Did we get an error?
if (got == SOCKET_ERROR)
{
*len = 0;
if (m_SocketState == CONN_CLOSED)
{
return( mLastError = HXR_NET_SOCKET_INVALID );
}
int code;
code = sockObj->HXWSAGetLastError();
// Translate the error
switch (code)
{
case WSAEWOULDBLOCK:
case WSAEINPROGRESS:
return( mLastError = HXR_WOULD_BLOCK );
case WSAEFAULT:
case WSAENOTCONN:
case WSAENOTSOCK:
return( mLastError = HXR_NET_SOCKET_INVALID );
case WSAENETDOWN:
return( mLastError = HXR_GENERAL_NONET );
case WSAEINTR:
return( mLastError = HXR_BLOCK_CANCELED );
case WSAEMSGSIZE:
return( mLastError = HXR_MSG_TOOLARGE);
case WSAETIMEDOUT:
case WSAESHUTDOWN:
case WSAECONNABORTED:
return( mLastError = HXR_SERVER_DISCONNECTED );
case WSAECONNRESET:
/*
* WinSock Recvfrom() Now Returns WSAECONNRESET Instead of Blocking or Timing Out (Q263823)
* workaround
*/
if (!m_bIgnoreWSAECONNRESET)
{
return( mLastError = HXR_SERVER_DISCONNECTED );
}
else
{
return( mLastError = HXR_WOULD_BLOCK );
}
default:
return( mLastError = HXR_NET_READ ); // Error we don't know what to do about
}
// Shouldn't really get here
return( mLastError );
}
else if (got == 0 && *len != 0)
{
*len = 0;
if (m_SocketState == CONN_CLOSED)
{
return( mLastError = HXR_NET_SOCKET_INVALID );
}
else
{
return( mLastError = HXR_SERVER_DISCONNECTED );
}
}
else
{
// This should be our exit point for successful read
*len = got;
return( HXR_OK );
}
}
}
HX_RESULT
win_net::readfrom (REF(IHXBuffer*) pBuffer,
REF(UINT32) ulAddress,
REF(UINT16) ulPort)
{
int got = 0;
UINT16 size = 0;
#ifndef _DEMPSEY
DEBUGOUTSTR( "win_net::readfrom()\r\n" );
#endif // !_DEMPSEY
pBuffer = NULL;
ulAddress = 0;
ulPort = 0;
if (get_sock() == INVALID_SOCKET || callRaConnect)
{
// Not connected
return( mLastError = HXR_NET_SOCKET_INVALID );
}
/* We want to read data even if we have received CloseNotification.
* This is because some unread data may be still be in the pipe
* - RA 10/01/1997
*/
if (m_SocketState != CONN_OPEN && m_SocketState != CONN_CLOSED)
{
// No
// We won't be able to write anything here, so clear this
// we'll return why we didn't write anything.
switch( m_SocketState )
{
case CONN_DNS_INPROG:
case CONN_CONNECT_INPROG:
case CONN_CLOSING:
return( mLastError = HXR_WOULD_BLOCK );
case CONN_CLOSED:
return( mLastError = HXR_NET_SOCKET_INVALID );
case CONN_NO_CONN:
#ifndef WIN32_PLATFORM_PSPC
return( DoStartAsyncConn() );
#else
HX_ASSERT(0 && "No Async net");
return( HXR_NET_READ );
#endif
case CONN_DNS_FAILED:
return( mLastError = HXR_DNR );
case CONN_CONNECT_FAILED:
return( mLastError = HXR_NET_CONNECT );
default:
// HUH???
HX_ASSERT (FALSE);
return( mLastError = HXR_NET_READ );
};
}
else
{
int fromlen;
struct sockaddr_in from;
fromlen = sizeof( from );
got = sockObj->HXrecvfrom( get_sock(), m_pInBuffer, TCP_BUF_SIZE, 0, (struct sockaddr*)&from, &fromlen );
// Did we get an error?
if (got == SOCKET_ERROR)
{
if (m_SocketState == CONN_CLOSED)
{
return( mLastError = HXR_NET_SOCKET_INVALID );
}
int code;
code = sockObj->HXWSAGetLastError();
// Translate the error
switch (code)
{
case WSAEWOULDBLOCK:
case WSAEINPROGRESS:
return( mLastError = HXR_WOULD_BLOCK );
case WSAEFAULT:
case WSAENOTCONN:
case WSAENOTSOCK:
return( mLastError = HXR_NET_SOCKET_INVALID );
case WSAENETDOWN:
return( mLastError = HXR_GENERAL_NONET );
case WSAEINTR:
return( mLastError = HXR_BLOCK_CANCELED );
case WSAEMSGSIZE:
return( mLastError = HXR_MSG_TOOLARGE);
case WSAETIMEDOUT:
case WSAESHUTDOWN:
case WSAECONNABORTED:
return( mLastError = HXR_SERVER_DISCONNECTED );
case WSAECONNRESET:
/*
* WinSock Recvfrom() Now Returns WSAECONNRESET Instead of Blocking or Timing Out (Q263823)
* workaround
*/
if (!m_bIgnoreWSAECONNRESET)
{
return( mLastError = HXR_SERVER_DISCONNECTED );
}
else
{
return( mLastError = HXR_WOULD_BLOCK );
}
default:
return( mLastError = HXR_NET_READ ); // Error we don't know what to do about
}
// Shouldn't really get here
return( mLastError );
}
else if (got == 0)
{
if (m_SocketState == CONN_CLOSED)
{
return( mLastError = HXR_NET_SOCKET_INVALID );
}
else
{
return( mLastError = HXR_SERVER_DISCONNECTED );
}
}
else
{
// This should be our exit point for successful read
CHXTimeStampedBuffer* pTimeBuffer = new CHXTimeStampedBuffer;
pTimeBuffer->AddRef();
pTimeBuffer->SetTimeStamp(HX_GET_TICKCOUNT());
pTimeBuffer->Set((UCHAR*)m_pInBuffer, got);
pBuffer = (IHXBuffer*) pTimeBuffer;
ulAddress = DwToHost(from.sin_addr.s_addr);
ulPort = WToHost(from.sin_port);
return( HXR_OK );
}
}
}
ULONG32 win_net::get_addr()
{
hostent *pHost = (hostent *)m_AsyncAddress;
ULONG32 addr = 0;
// if CurrentAddr is set, we must have passed
// a dotted IP address...
if (CurrentAddr)
{
addr = CurrentAddr;
}
else if (pHost)
{
addr = (ULONG32) (*(ULONG32*)pHost->h_addr);
}
return addr;
}
UINT16 win_net::get_local_port()
{
sockaddr_in addr;
int addr_len = sizeof addr;
memset(&addr, 0, HX_SAFESIZE_T(addr_len));
int ret = sockObj->HXgetsockname(get_sock(), (sockaddr*)&addr, &addr_len);
return (ret < 0) ? -1: WToHost(addr.sin_port);
}
// we need it for dns_find_ip_addr since async stuff needs a window handle...
HX_RESULT win_net::SetWindowHandle(ULONG32 handle)
{
m_hInst = (HINSTANCE)handle;
return HXR_OK;
}
HX_RESULT win_net::dns_find_ip_addr(const char * host, UINT16 blocking)
{
if(!host)
{
mLastError = HXR_DNR;
return mLastError;
}
if(get_sock() < 0)
{
mLastError = HXR_NET_SOCKET_INVALID;
return mLastError;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?