win_net.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,166 行 · 第 1/4 页
CPP
2,166 行
/* ***** BEGIN LICENSE BLOCK *****
* Source last modified: $Id: win_net.cpp,v 1.6.2.3 2004/07/09 01:46:44 hubbe Exp $
*
* Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file,
* are subject to the current version of the RealNetworks Public
* Source License (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the current version of the RealNetworks Community
* Source License (the "RCSL") available at
* http://www.helixcommunity.org/content/rcsl, in which case the RCSL
* will apply. You may also obtain the license terms directly from
* RealNetworks. You may not use this file except in compliance with
* the RPSL or, if you have a valid RCSL with RealNetworks applicable
* to this file, the RCSL. Please see the applicable RPSL or RCSL for
* the rights, obligations and limitations governing use of the
* contents of the file.
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL") in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your version of
* this file only under the terms of the GPL, and not to allow others
* to use your version of this file under the terms of either the RPSL
* or RCSL, indicate your decision by deleting the provisions above
* and replace them with the notice and other provisions required by
* the GPL. If you do not delete the provisions above, a recipient may
* use your version of this file under the terms of any one of the
* RPSL, the RCSL or the GPL.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the
* portions it created.
*
* This file, and the files included with this file, is distributed
* and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
* ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxtypes.h"
#ifdef _WIN16
#include <stdlib.h>
#endif _WIN16
#include <stdio.h>
#include <string.h>
/* mcast_multiple_if test */
#ifndef _WINCE
#include <iostream.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#endif /* _WINCE */
#include "hxslist.h"
#include "platform/win/sock.h"
#include "platform/win/hxsock.h" // Low level socket calls
#include "hxthread.h"
#include "hxcom.h"
#include "hxengin.h"
#include "threngin.h"
#include "platform/win/win_net.h" // Our declaration
#include "platform/win/casynnet.h" // Declaration of async socket notifier
#include "netbyte.h"
#include "hxbuffer.h"
#include "timebuff.h"
#include "hxtick.h"
#include "debugout.h" // Debug macros
#include "hxstrutl.h"
#include "hxheap.h"
#include "thrdconn.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
static WinsockManager OnlyOneOfThisInTheWholeProgram;
//#define _LOGSMIL 1
win_net::win_net() // PostThreadMessage
{
set_sock( INVALID_SOCKET );
mLastError = HXR_OK;
callRaConnect = 1;
bReadyToWrite = 0;
m_SocketState = CONN_CLOSED;
#ifndef WIN32_PLATFORM_PSPC
m_hAsyncHandle = NULL;
#endif
m_AsyncAddress = NULL;
CurrentAddr = 0;
m_DNSOnly = FALSE;
m_pAsyncHost = NULL;
InBlockingMode = 0;
m_lRefCount = 0;
m_pInBuffer = new char[TCP_BUF_SIZE];
m_bReuseAddr = FALSE;
m_bReusePort = FALSE;
m_bIgnoreWSAECONNRESET = FALSE;
}
win_net::~win_net()
{
#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;
if (m_AsyncAddress)
{
delete [] m_AsyncAddress;
m_AsyncAddress = NULL;
}
HX_VECTOR_DELETE(m_pAsyncHost);
delete[] m_pInBuffer;
}
win_net * win_net::new_socket(UINT16 type)
{
win_net* c = NULL;
if (sockObj)
{
switch(type)
{
case HX_TCP_SOCKET:
c = new win_TCP;
break;
case HX_UDP_SOCKET:
c = new win_UDP;
break;
}
}
return(c);
}
// init_drivers() should do any network driver initialization here
// params is a pointer to a platform specfic defined struct that
// contains an required initialization data
HX_RESULT win_net::init_drivers(void *params)
{
if(!sockObj)
sockObj = new CHXSock;
if(!sockObj)
return(HXR_OUTOFMEMORY);
return(HXR_OK);
}
/* close_drivers() should close any network drivers used by the program
NOTE: The program MUST not make any other calls to the network drivers
until init_drivers() has been called */
HX_RESULT win_net::close_drivers(void *params)
{
if(sockObj)
{
sockObj->HXWSACleanup();
delete sockObj;
sockObj = NULL;
}
return(HXR_OK);
}
HX_RESULT win_net::host_to_ip_str( char *host, char *ip, UINT32 ulIPBufLen)
{
ULONG32 dwAddress;
IN_ADDR rInAddress;
HX_RESULT theErr;
PHOSTENT pHostEntry;
theErr = HXR_OK;
// Let's look for this in the cache first
if (conn::is_cached( host, &dwAddress))
{
// Found it, copy the 32bit address into rInAddress w/o calling memcpy()
rInAddress = *(IN_ADDR *)&dwAddress;
}
else
{
// Do DNS on the host name
if (!(pHostEntry = sockObj->HXgethostbyname( host )))
{
// Error
theErr = HXR_DNR;
}
// Return w/o attempting any copies if there's an error
if (HXR_OK != theErr)
{
goto FuncExit;
}
// copy the ip address into rInAddress w/o calling memcpy()
rInAddress = *(IN_ADDR *)(pHostEntry->h_addr);
}
// Convert the ULONG32 IP address into a string and copy it into ip
SafeStrCpy( ip, sockObj->HXinet_ntoa( rInAddress ) , ulIPBufLen);
// Single exit point
FuncExit:
return( theErr );
}
ULONG32 win_net::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
ULONG32 win_net::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
HX_RESULT win_net::init_win(UINT16 type, UINT32 local_addr,
UINT16 port, UINT16 blocking)
{
int s;
s = sockObj->HXsocket(PF_INET, type, 0);
if (s == INVALID_SOCKET)
{
mLastError = HXR_NET_SOCKET_INVALID;
return mLastError;
}
InBlockingMode = 1;
{
struct linger Ling;
Ling.l_onoff = 0;
Ling.l_linger = 0;
if (callRaConnect && sockObj->HXsetsockopt(s, SOL_SOCKET, SO_LINGER,
(char *)&Ling, sizeof(Ling)) != 0)
{
if(!InBlockingMode)
return HXR_BLOCK_CANCELED;
int code;
code = sockObj->HXWSAGetLastError();
mLastError = HXR_NET_SOCKET_INVALID;
InBlockingMode = 0;
return mLastError;
}
}
if(!InBlockingMode)
return HXR_BLOCK_CANCELED;
InBlockingMode = 0;
{
if (sockObj->HXsetsockopt(s, SOL_SOCKET, SO_REUSEADDR,
(const char *)&m_bReuseAddr, sizeof(m_bReuseAddr)) != 0)
{
int code;
code = sockObj->HXWSAGetLastError();
mLastError = HXR_NET_SOCKET_INVALID;
return mLastError;
}
// Reuse port is not supported on win's right now...
/*
if (sockObj->HXsetsockopt(s, SOL_SOCKET, SO_REUSEPORT,
(const char *)&m_bReusePort, sizeof(m_bReusePort)) != 0)
{
int code;
code = sockObj->HXWSAGetLastError();
mLastError = HXR_NET_SOCKET_INVALID;
return mLastError;
}
*/
}
struct sockaddr_in SockAddr;
memset(&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = sockObj->HXhtonl(local_addr);
SockAddr.sin_port = sockObj->HXhtons(port);
if (sockObj->HXbind(s, (sockaddr*)&SockAddr, sizeof(SockAddr)) < 0)
{
//perror("bind");
goto err;
}
{
unsigned long lMode = 1;
if (!blocking && sockObj->HXioctlsocket(s, FIONBIO, &lMode) < 0)
{
goto err;
}
}
if (!callRaConnect)
{
m_SocketState = CONN_OPEN;
}
else
{
m_SocketState = CONN_NO_CONN;
}
set_sock( s );
return HXR_OK;
err:
sockObj->HXclosesocket(s);
mLastError = HXR_NET_CONNECT;
return mLastError;
}
HX_RESULT win_net::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform)
{
DEBUGOUTSTR( "win_net::connect()\r\n" );
m_hInst = (HINSTANCE)ulPlatform;
if (!blocking)
{
#ifndef WIN32_PLATFORM_PSPC
return( ConnectAsync( host, port ) );
#else
HX_ASSERT(0 && "No Async connect");
#endif
}
else
{
bReadyToWrite = 0;
if(!host)
{
mLastError = HXR_DNR;
return mLastError;
}
if(get_sock() < 0)
{
mLastError = HXR_NET_SOCKET_INVALID;
return mLastError;
}
struct in_addr addr;
char* pTemp = strrchr(host, '.');
if (pTemp && isdigit(*(pTemp + 1)))
{ /* IP address. */
InBlockingMode = 1;
addr.s_addr = sockObj->HXinet_addr(host);
if(!InBlockingMode)
return HXR_BLOCK_CANCELED;
InBlockingMode = 0;
if ((UINT)addr.s_addr == (UINT)-1)
{
mLastError = HXR_DNR;
return mLastError;
}
m_SocketState = CONN_CONNECT_INPROG;
}
else
{ /* Host name. */
InBlockingMode = 1;
struct hostent *h = sockObj->HXgethostbyname(host);
if(!InBlockingMode)
return HXR_BLOCK_CANCELED;
InBlockingMode = 0;
if (!h || !h->h_addr )
{
mLastError = HXR_DNR;
return mLastError;
}
memcpy(&addr, h->h_addr, sizeof(struct in_addr)); /* Flawfinder: ignore */
// Rahul
m_AsyncPort = port;
if (m_pAsyncHost != host)
{
HX_VECTOR_DELETE(m_pAsyncHost);
m_pAsyncHost = ::new_string(host);
}
}
struct sockaddr_in SockAddr;
memset(&SockAddr, 0, sizeof(SockAddr));
SockAddr.sin_family = AF_INET;
SockAddr.sin_addr.s_addr = *(long*)&addr;
SockAddr.sin_port = sockObj->HXhtons(port);
// this stores info about current addr
CurrentAddr = *(ULONG32*)&addr;
InBlockingMode = 1;
if(callRaConnect && sockObj->HXconnect(get_sock(), (sockaddr*)&SockAddr, sizeof(SockAddr)))
{
if(!InBlockingMode)
return HXR_BLOCK_CANCELED;
InBlockingMode = 0;
int code;
code = sockObj->HXWSAGetLastError();
if(!blocking && (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS))
{
mConnectionOpen = 1;
return HXR_OK;
}
mLastError = HXR_NET_CONNECT;
return mLastError;
}
if(!InBlockingMode)
return HXR_BLOCK_CANCELED;
InBlockingMode = 0;
mConnectionOpen = 1;
m_SocketState = CONN_OPEN;
bReadyToWrite = 1;
#ifdef WIN32_PLATFORM_PSPC
// Without asyncronous notification we cannot tolerate Asyncronous connect
// so set non-blocking here rather than at connect
ULONG lMode = 1;
sockObj->HXioctlsocket(get_sock(), FIONBIO, &lMode);
if (mCallBack)
{
mCallBack->Func(CONNECT_NOTIFICATION);
}
#endif
return HXR_OK;
}
}
//-------------------------------------------------
#if defined(HELIX_FEATURE_NETWORK_USE_SELECT)
HX_RESULT
win_net::WaitforSelect(void *pE,void *pC)
{
ThreadEngine *pEngine = (ThreadEngine *)pE;
ThreadedConn *pProcessConn = (ThreadedConn*) pC;
if (!pEngine)
return HXR_FAIL;
CHXMapPtrToPtr::Iterator ndxConn;
CHXMapPtrToPtr* pSockMap = pEngine->GetSockMap();
fd_set readfds,exceptfds;
BOOL bHaveSock = FALSE;
HX_RESULT theErr = HXR_OK;
FD_ZERO(&readfds);
FD_ZERO(&exceptfds);
for (ndxConn = pSockMap->Begin();
ndxConn != pSockMap->End(); ++ndxConn)
{
ThreadedConn* pConn = (ThreadedConn*) (*ndxConn);
if (pProcessConn &&
pConn != pProcessConn)
continue; // dont process other connections while closing
if (!pConn->connection_really_open())
continue;
if (!pConn->GetActualConn())
continue;
unsigned int s = pConn->get_sock();
if (s != INVALID_SOCKET)
{
FD_SET(s,&readfds);
FD_SET(s,&exceptfds);
bHaveSock = TRUE;
}
}
if (!bHaveSock)
return HXR_FAIL;
theErr = sockObj->HXselect(NULL,&readfds,NULL,NULL/*&exceptfds*/,NULL);
if (theErr == SOCKET_ERROR)
{
theErr = sockObj->HXWSAGetLastError();
}
else
{
theErr = HXR_OK;
}
// check for read ready
for (ndxConn = pSockMap->Begin();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?