win_net.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,166 行 · 第 1/4 页
CPP
2,166 行
ndxConn != pSockMap->End(); ++ndxConn)
{
ThreadedConn* pConn = (ThreadedConn*) (*ndxConn);
if (pProcessConn &&
pConn != pProcessConn)
continue; // dont process other connections while closing
if (!pConn->GetActualConn())
continue;
int s = pConn->get_sock();
if (s != INVALID_SOCKET)
{
if (FD_ISSET(s,&readfds))
pConn->DoRead(TRUE);
}
}
return theErr;
}
HX_RESULT
win_net::CheckForConnection()
{
HX_ASSERT(m_SocketState == CONN_LISTENNING);
if (m_SocketState != CONN_LISTENNING)
return HXR_FAIL;
sockaddr_in addr;
int len = sizeof(sockaddr_in);
memset(&addr, 0, len);
SOCKET sock = sockObj->HXaccept(get_sock(), (sockaddr*)&addr, &len);
if ( sock == INVALID_SOCKET )
{
int code = sockObj->HXWSAGetLastError();
// igno all errors... r
return HXR_WOULD_BLOCK;
}
win_net* c = (win_net*)conn::actual_new_socket(HX_TCP_SOCKET);
c->AddRef();
conn::add_connection_to_list ( c );
if ( c )
{
c->set_sock(sock);
c->connect_accept((ULONG32)m_hInst, addr);
if (mCallBack && (m_SocketState == CONN_LISTENNING))
{
mCallBack->Func(ACCEPT_NOTIFICATION, TRUE, (conn*)c);
}
}
HX_RELEASE(c);
return HXR_OK;
}
#endif //defined(HELIX_FEATURE_NETWORK_USE_SELECT)
// This function actually starts an async DNS request
// It does it on either the first read or first write after we
#ifndef WIN32_PLATFORM_PSPC
// call ConnectAsync();
HX_RESULT win_net::DoStartAsyncConn()
{
DEBUGOUTSTR( "win_net::DoStartAsyncConn()\r\n" );
if (!m_pAsyncHost)
{
return (mLastError = HXR_FAILED);
}
if (!m_AsyncAddress)
{
m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
}
if (!m_AsyncAddress)
{
return (mLastError = HXR_OUTOFMEMORY);
}
m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , TRUE);
m_AsyncNotifier->DoAsyncDNS( this, m_pAsyncHost, m_AsyncAddress, MAXGETHOSTSTRUCT );
m_SocketState = CONN_DNS_INPROG;
return( mLastError = HXR_WOULD_BLOCK );
}
// This method get's called by connect() in the case of an async request
// It doesn't however actually start the connection. It just registers
// that we need to do the connection. DoStartAsyncConn() will really do it.
HX_RESULT win_net::ConnectAsync( LPCSTR host, UINT16 port )
{
DEBUGOUTSTR( "win_net::ConnectAsync()\r\n" );
bReadyToWrite = 0;
if (!host)
{
mLastError = HXR_DNR;
return mLastError;
}
if (get_sock() == INVALID_SOCKET)
{
mLastError = HXR_NET_SOCKET_INVALID;
return mLastError;
}
struct in_addr addr;
char* pTemp = strrchr(host, '.');
if (pTemp && atoi(pTemp + 1))
{ /* IP address. */
addr.s_addr = sockObj->HXinet_addr(host);
if ((UINT)addr.s_addr == (UINT)-1)
{
mLastError = HXR_DNR;
return mLastError;
}
else
{
LPSTR pTemp;
hostent *pHost;
if (!m_AsyncAddress)
{
m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
}
if (!m_AsyncAddress)
{
mLastError = HXR_OUTOFMEMORY;
return (mLastError);
}
pHost = (hostent *)m_AsyncAddress;
// this stores info about current addr
CurrentAddr = *(ULONG32 *)&addr;
m_AsyncPort = port;
pTemp = (LPSTR)&addr.s_addr;
pHost->h_addr_list = &pTemp;
CB_DNSComplete( TRUE );
}
}
else if (conn::is_cached((char *)host,(ULONG32 *) &addr))
{
LPSTR pTemp;
hostent *pHost;
if (!m_AsyncAddress)
{
m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
}
if (!m_AsyncAddress)
{
mLastError = HXR_OUTOFMEMORY;
return (mLastError);
}
pHost = (hostent *)m_AsyncAddress;
// this stores info about current addr
CurrentAddr = *(ULONG32 *)&addr;
m_AsyncPort = port;
pTemp = (LPSTR)&addr.s_addr;
pHost->h_addr_list = &pTemp;
CB_DNSComplete( TRUE );
}
else
{
// Save the parameters, and tell ourselves we're starting up
m_AsyncPort = port;
if (m_pAsyncHost != host)
{
HX_VECTOR_DELETE(m_pAsyncHost);
m_pAsyncHost = ::new_string(host);
}
m_SocketState = CONN_NO_CONN;
return(DoStartAsyncConn());
}
return( HXR_OK );
}
// Once async DNS has commpleted then we'll call this guy to do the
// connection (again asynchronously).
void win_net::ContinueAsyncConnect()
{
hostent *pHost;
struct in_addr addr;
DEBUGOUTSTR( "win_net::ContinueAsyncConnect()\r\n" );
pHost = (hostent *)m_AsyncAddress;
if (!pHost)
return;
memcpy( &(addr.s_addr), pHost->h_addr, sizeof( addr.s_addr ) ); /* Flawfinder: ignore */
m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst ,TRUE);
m_AsyncNotifier->DoAsyncSelect( this );
struct sockaddr_in SockAddr;
memset( &SockAddr, 0, sizeof( SockAddr ) );
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = *(long*)&(addr.s_addr);
SockAddr.sin_port = sockObj->HXhtons( m_AsyncPort );
if(callRaConnect && sockObj->HXconnect( get_sock(), (sockaddr*)&SockAddr, sizeof( SockAddr ) ))
{
int code;
code = sockObj->HXWSAGetLastError();
if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS)
{
m_SocketState = CONN_CONNECT_INPROG;
mConnectionOpen = 1;
return;
}
mLastError = HXR_NET_CONNECT;
m_SocketState = CONN_CONNECT_FAILED;
return;
}
m_SocketState = CONN_CONNECT_INPROG;
mConnectionOpen = 1;
return;
}
// Called by the notifier to tell us that the DNS request completed
void win_net::CB_DNSComplete( int iSuccess )
{
DEBUGOUTSTR( "CB_DNSComplete()\r\n" );
mDNSDone = TRUE;
if (iSuccess && m_pAsyncHost)
{
conn::add_to_cache(m_pAsyncHost, get_addr());
}
if (m_DNSOnly)
{
if (iSuccess)
{
mHostIPValid = TRUE;
mHostIPAddr = get_addr();
}
else
{
mHostIPValid = FALSE;
}
}
else
{
if (iSuccess)
{
m_SocketState = CONN_CONNECT_INPROG;
ContinueAsyncConnect();
}
else
{
m_SocketState = CONN_DNS_FAILED;
}
}
if (mCallBack)
{
mCallBack->Func(DNS_NOTIFICATION, iSuccess);
}
}
// Called by the notifier to tell us that the Connection completed
void win_net::CB_ConnectionComplete( int iSuccess )
{
DEBUGOUTSTR( "CB_ConnectionComplete()\r\n" );
if (iSuccess)
{
m_SocketState = CONN_OPEN;
if (mCallBack)
{
mCallBack->Func(CONNECT_NOTIFICATION);
}
}
else
{
m_SocketState = CONN_CONNECT_FAILED;
if (mCallBack)
{
mCallBack->Func(CONNECT_NOTIFICATION, FALSE);
}
}
}
// Called by the notifier when data ready for read/write
void win_net::CB_ReadWriteNotification( int iType )
{
#ifndef _DEMPSEY
// noisy output
DEBUGOUTSTR( "CB_ReadWriteNotification()....\r\n" );
#endif // _DEMPSEY
// Should do something here....
if (mCallBack && (m_SocketState == CONN_OPEN))
{
if (iType == FD_WRITE)
{
mCallBack->Func(WRITE_NOTIFICATION);
}
else if (iType == FD_READ)
{
mCallBack->Func(READ_NOTIFICATION);
}
//mCallBack->callback_task( HX_UDP_CALLBACK, NULL );
}
}
void win_net::CB_AcceptNotification()
{
DEBUGOUTSTR( "CB_AcceptNotification()....\r\n" );
HX_ASSERT(m_SocketState == CONN_LISTENNING);
win_net* c = (win_net*)conn::actual_new_socket(HX_TCP_SOCKET);
c->AddRef();
conn::add_connection_to_list ( c );
if ( c )
{
sockaddr_in addr;
int len = sizeof(addr);
SOCKET sock = sockObj->HXaccept(get_sock(), (sockaddr*)&addr, &len);
if ( sock != INVALID_SOCKET)
{
c->set_sock(sock);
c->connect_accept((ULONG32)m_hInst, addr);
if (mCallBack && (m_SocketState == CONN_LISTENNING))
{
mCallBack->Func(ACCEPT_NOTIFICATION, TRUE, (conn*)c);
}
}
}
HX_RELEASE(c);
}
void win_net::CB_CloseNotification()
{
DEBUGOUTSTR( "CB_CloseNotification()....\r\n" );
m_SocketState = CONN_CLOSED;
if (mCallBack)
{
mCallBack->Func(CLOSE_NOTIFICATION);
}
}
#endif
HX_RESULT win_net::connect( sockaddr_in *addr )
{
if(callRaConnect && sockObj->HXconnect( get_sock(), (sockaddr*)addr, sizeof( addr ) ))
{
mLastError = HXR_NET_CONNECT;
return mLastError;
}
mConnectionOpen = 1;
return HXR_OK;
}
HX_RESULT win_net::write(void * buf, UINT16 *len)
{
int got;
DEBUGOUTSTR( "win_net::write()\r\n" );
if (get_sock() == INVALID_SOCKET)
{
// Not connected
return( mLastError = HXR_NET_SOCKET_INVALID );
}
if (m_SocketState != CONN_OPEN ) //&& m_SocketState != CONN_DNS_INPROG)
{
// 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???
assert( 0 );
return( mLastError = HXR_NET_READ );
};
}
else
{
got = sockObj->HXsend( get_sock(), (char *)buf, *len, 0 );
if (got == -1)
{
int code;
*len = 0;
code = sockObj->HXWSAGetLastError();
// Mask the "so what?" errors
if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS)
{
return HXR_WOULD_BLOCK;
}
else
{
mLastError = HXR_NET_WRITE;
return mLastError;
}
}
//#if defined(_DEBUG) && defined(_LOGSMIL)
// if (::HXDebugOptionEnabled("zLogSMIL"))
//{FILE* f1 = ::fopen("e:\\temp\\foo.txt", "a+"); ::fwrite(buf, got, 1, f1);::fclose(f1);}
//#endif
*len = got;
return HXR_OK;
}
}
HX_RESULT win_net::writeto(void * buf, UINT16 *len, ULONG32 addr, UINT16 port)
{
//sendto
int got;
sockaddr_in resend_addr;
::memset( &resend_addr, 0, sizeof( resend_addr ) );
resend_addr.sin_family = AF_INET;
resend_addr.sin_addr.s_addr = addr;
resend_addr.sin_port = sockObj->HXhtons(port);
got = sockObj->HXsendto(get_sock(), (char *) buf, *len, 0, (sockaddr *)&resend_addr, sizeof (resend_addr));
if (got == -1)
{
int code;
*len = 0;
code = sockObj->HXWSAGetLastError();
// Mask the "so what?" errors
if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS)
{
return HXR_WOULD_BLOCK;
}
else
{
mLastError = HXR_NET_WRITE;
return mLastError;
}
}
*len = got;
return HXR_OK;
}
HX_RESULT win_net::WriteComplete (char * Buffer, int length)
{
int sent = 0;
unsigned short cur_sent=0;
while(sent < length)
{
cur_sent = length - sent;
HX_RESULT ret = write(Buffer + sent, &cur_sent);
if(ret != HXR_OK && ret != HXR_WOULD_BLOCK)
break;
sent += cur_sent;
}
// m_SocketState = CONN_NO_CONN;
if(sent < length)
{
mLastError = HXR_NET_WRITE;
return mLastError;
}
return HXR_OK;
}
int win_net::ReadyToWrite()
{
if(get_sock() < 0)
{
bReadyToWrite = 0;
return bReadyToWrite;
}
if(bReadyToWrite)
return 1;
fd_set writefds;
FD_ZERO(&writefds);
FD_SET((UINT32)get_sock(), &writefds);
TIMEVAL timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;
if(sockObj->HXselect(0, NULL, &writefds,NULL, &timeout) == 1)
bReadyToWrite = 1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?