📄 unix_net.cpp
字号:
} return ret;}HX_RESULTunix_UDP::set_multicast(){#ifdef NO_MULTICAST return HXR_MULTICAST_UDP;#endif /* NO_MULTICAST */ INT32 ret; sockaddr_in addr;#if defined _AIX42 size_t addr_len = sizeof addr;#elif defined _HPUX || defined _OSF1 int addr_len = sizeof addr;#else socklen_t addr_len = sizeof addr;#endif if (get_sock() == INVALID_SOCKET) { // Not connected mLastError = HXR_NET_SOCKET_INVALID; return mLastError; } memset(&addr, 0, HX_SAFESIZE_T(addr_len)); ret = getsockname(get_sock(), (sockaddr*)&addr, &addr_len); if (ret < 0) { return HXR_MULTICAST_UDP; }/* * Linux and Solairs seem to return 127.0.0.1 from getsockname() which they * don't accept as a valid interface in setsockopt(IP_MULTICAST_IF) */#if defined _LINUX || defined _SOLARIS addr.sin_addr.s_addr = INADDR_ANY;#endif /* _LINUX || _SOLARIS */#ifdef _BEOS // FIXME no multicast for BeOS return HXR_MULTICAST_UDP;#else ret = ::setsockopt(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 /* _BEOS */}HX_RESULTunix_UDP::set_multicast_ttl(unsigned char ttl){#ifdef NO_MULTICAST return HXR_MULTICAST_UDP;#endif /* NO_MULTICAST */ INT32 ret; unsigned char ttl_proxy; ttl_proxy = ttl;#ifdef _BEOS // FIXME no multicast for BeOS return HXR_MULTICAST_UDP;#else if (get_sock() == INVALID_SOCKET) { // Not connected return( mLastError = HXR_NET_SOCKET_INVALID ); } ret = ::setsockopt(get_sock(), IPPROTO_IP, IP_MULTICAST_TTL, (char*) &ttl_proxy, sizeof (ttl_proxy)); if (ret < 0) { return HXR_MULTICAST_UDP; } return HXR_OK;#endif /* _BEOS */}HX_RESULT unix_UDP::join_multicast_group(ULONG32 addr, ULONG32 if_addr){ #if defined(_BEOS) return HXR_NOTIMPL; #else int ret; ip_mreq multicast_group; if (get_sock() == INVALID_SOCKET) { // Not connected return( mLastError = HXR_NET_SOCKET_INVALID ); } u_char ttl = 254; // As Per Sujal. ret = ::setsockopt(get_sock(), IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)); if (ret == -1) { return HXR_MULTICAST_JOIN; } multicast_group.imr_multiaddr.s_addr = htonl(addr);#ifdef _UNIX multicast_group.imr_interface.s_addr = htonl(INADDR_ANY);#elif multicast_group.imr_interface.s_addr = htonl(if_addr);#endif ret = ::setsockopt(get_sock(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &multicast_group, sizeof (multicast_group)); if (ret < 0) { return HXR_MULTICAST_JOIN; } return HXR_OK;#endif}HX_RESULT unix_UDP::leave_multicast_group(ULONG32 addr, ULONG32 if_addr){#if defined(_BEOS) return HXR_NOTIMPL; #else 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 = htonl(addr); multicast_group.imr_interface.s_addr = htonl(if_addr); ret = ::setsockopt(get_sock(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*) &multicast_group, sizeof (multicast_group)); if (ret == -1) { return HXR_GENERAL_MULTICAST; } return HXR_OK;#endif}HX_RESULT unix_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 = htonl(ulInterface); ret = setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, (char*)&addr, sizeof(addr)); if(ret == -1) ret = HXR_GENERAL_MULTICAST; return ret;}HX_RESULT unix_UDP::set_broadcast(BOOL enable){ int ret; int s = get_sock(); if(s == INVALID_SOCKET) { return( mLastError = HXR_NET_SOCKET_INVALID ); } ret = setsockopt( s, SOL_SOCKET, SO_BROADCAST, (char*)&enable, sizeof(UINT32) ); if(ret == -1) ret = HXR_BIND; return ret;}HX_RESULT unix_UDP::set_send_size(UINT32 send_size){#ifdef _BEOS // Be is messed up return -1;#else int s = get_sock(); int ret = 0;again: ret = setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char*)&send_size, sizeof(INT32)); if (ret < 0 && send_size > 8192) { send_size >>= 1; goto again; } return ret;#endif}HX_RESULT unix_net::writeto( void * buf, UINT16 *len, ULONG32 addr, UINT16 port){ 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 = htons(port); got = sendto(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;}ULONG32 unix_net::get_addr(){ return m_sSockAddrIn.sin_addr.s_addr;}UINT16 unix_net::get_local_port(){ sockaddr_in addr;#if defined _AIX42 size_t addr_len = sizeof addr;#elif defined _HPUX || defined _OSF1 int addr_len = sizeof addr;#else socklen_t addr_len = sizeof addr;#endif memset(&addr, 0, HX_SAFESIZE_T(addr_len)); int ret = getsockname(get_sock(), (sockaddr*)&addr, &addr_len); return (ret < 0) ? -1 : WToHost(addr.sin_port);}HX_RESULT unix_net::dns_find_ip_addr(const char * host, UINT16 blocking){ mHostIPValid = FALSE; mDNSDone = TRUE; blocking = GetAsyncDNSPref() ? 1 : blocking; if(!host) { mLastError = HXR_DNR; return mLastError; } if(get_sock() < 0) { mLastError = HXR_NET_SOCKET_INVALID; return mLastError; } if (conn::is_cached((char *) host, &mHostIPAddr)) { mHostIPValid = TRUE; mLastError = HXR_OK; if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, TRUE); } return HXR_OK; } //Check for a dot format IP string. char* pTemp = (char*)strrchr(host, '.'); if (pTemp && isdigit(*(pTemp + 1))) { /* IP address. */ mHostIPValid = FALSE; mHostIPAddr = 0; mDNSDone = TRUE; m_sSockAddrIn.sin_addr.s_addr = inet_addr(host); if ((UINT)m_sSockAddrIn.sin_addr.s_addr == (UINT)-1) { mLastError = HXR_DNR; return mLastError; } mHostIPValid = TRUE; mHostIPAddr = m_sSockAddrIn.sin_addr.s_addr; conn::add_to_cache((char *)host, mHostIPAddr); if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, TRUE); } return HXR_OK; } if( blocking ) { hostent *pHost = gethostbyname((char *) host); mHostIPValid = FALSE; mHostIPAddr = 0; mDNSDone = TRUE; if( !pHost || !pHost->h_addr ) { mLastError = HXR_DNR; return mLastError; } mHostIPValid = TRUE; struct in_addr** ppAddr = (struct in_addr**)(pHost->h_addr_list); mHostIPAddr = ppAddr[0]->s_addr; conn::add_to_cache((char *) host, mHostIPAddr); if (mCallBack) { mCallBack->Func(DNS_NOTIFICATION, TRUE); } return HXR_OK; } else { //Non blocking code here. if (m_pAsyncHost != host) { HX_VECTOR_DELETE(m_pAsyncHost); m_pAsyncHost = ::new_string(host); } //Tell everyone we just want DNS and no connect. m_DNSOnly = TRUE; //Start up the non-blocking DNS. DoStartAsyncConn(); }//blocking mLastError = HXR_OK; return mLastError;}BOOL unix_net::dns_ip_addr_found(BOOL* valid, ULONG32* addr){ if (mDNSDone) { *valid = mHostIPValid; *addr = mHostIPAddr; return TRUE; } else return FALSE;}void unix_net::add_read_request(){ read_pending = TRUE;}void unix_net::add_select(int *n, fd_set* readfds, fd_set* writefds, fd_set* exceptfds){ unix_net* un; int sock; if(!silly_unix_hack_initialized) { readers = new CHXSimpleList; silly_unix_hack_initialized = TRUE; } if(!unix_net::readers->IsEmpty()) { CHXSimpleList::Iterator i; for(i = unix_net::readers->Begin(); i != unix_net::readers->End(); ++i) { un = (unix_net*)(*i); sock = un->get_sock(); if(un->read_pending && sock >= 0) { if(sock > *n) *n = sock + 1; FD_SET(sock, readfds); } } }}void unix_net::process_select(int n, fd_set* readfds, fd_set* writefds, fd_set* exceptfds){ unix_net* un; int sock; if(!unix_net::readers->IsEmpty()) { CHXSimpleList::Iterator i, next; for(i = unix_net::readers->Begin(); i != unix_net::readers->End(); i = next) { next = i; ++next; un = (unix_net*)(*i); sock = un->get_sock(); if(sock >= 0) { if(FD_ISSET(sock, readfds)) { un->read_pending = FALSE; un->CB_ReadWriteNotification(0); } } } }}void unix_net::process_idle(){ unix_net* un; fd_set read_fds; struct timeval tv; int maxfd = 0; int sock = INVALID_SOCKET; if(!silly_unix_hack_initialized) { readers = new CHXSimpleList; silly_unix_hack_initialized = TRUE; } FD_ZERO(&read_fds); if(!unix_net::readers->IsEmpty()) { CHXSimpleList::Iterator i; for(i = unix_net::readers->Begin(); i != unix_net::readers->End(); ++i) { un = (unix_net*)(*i); //Hold on to this reference. un->AddRef(); //Check the progress of each unix_net object's async DNS //and connect. if( un->GetSocketState() == CONN_DNS_INPROG ) un->CheckOnDNS(); else if( un->GetSocketState() == CONN_CONNECT_INPROG ) un->ContinueAsyncConnect(); else if ( un->GetSocketState() == CONN_LISTENNING ) un->CheckForConnection(); sock = un->get_sock(); if(un->read_pending && sock >= 0) { if(sock > maxfd) maxfd = sock; FD_SET(sock, &read_fds); } //Release this reference. if( 0 == un->Release() ) { //This object just got deleted. Make sure we adjust //the iterator back to a valid one because deleting //the object an iterator points to invalidates the //iterator. //Make sure we don't iterate past the end with the //upcoming i++ in the for loop above. if( unix_net::readers->IsEmpty() ) { break; } //XXXgfw Can we do better then just setting it all //XXXgfw the way back to the begining? i = unix_net::readers->Begin(); } } } tv.tv_sec = 0; tv.tv_usec = 0; if(select(maxfd + 1, &read_fds, 0, 0, &tv) > 0) { if(!unix_net::readers->IsEmpty()) { CHXSimpleList::Iterator i, next; for(i = unix_net::readers->Begin(); i != unix_net::readers->End(); i = next) { next = i; ++next; un = (unix_net*)(*i); sock = un->get_sock(); if(un->read_pending && sock >= 0) { if(FD_ISSET(sock, &read_fds)) { un->read_pending = FALSE; un->CB_ReadWriteNotification(0); } } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -