📄 socket.cpp
字号:
{ cIntfAddr.Build(strIntf, strPort, m_iType); } catch(E_InetAddr e) { throw E_Socket("Unable to bind to " + strIntf + " on port " + strPort, e); } pAddr = (struct sockaddr*)cIntfAddr.GetInetAddr(); iAddrLen = sizeof(*cIntfAddr.GetInetAddr()); }#endif else { ASSERT(false); } // Bind the socket to the local address int iRc = bind(m_hSocket, pAddr, iAddrLen); if(iRc) { throw E_Socket("Unable to bind to " + strIntf + " on port " + strPort + ": " + GetErrorMsg(SYSTEM_NETWORK)); }} //------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Socket::Connect(const C_String& strPeer, const C_String& strPort){ // Try to resolve the given address struct sockaddr* pAddr; int iAddrLen; if(m_iDomain == AF_INET) { C_Inet4Addr cPeerAddr; try { cPeerAddr.Build(strPeer, strPort); } catch(E_InetAddr e) { throw E_Socket("Unable to connect to " + strPeer + " on port "+ strPort, e); } pAddr = (struct sockaddr*)cPeerAddr.GetInetAddr(); iAddrLen = sizeof(*cPeerAddr.GetInetAddr()); }#ifdef HAVE_IPV6 else if(m_iDomain == AF_INET6) { C_Inet6Addr cPeerAddr; try { cPeerAddr.Build(strPeer, strPort, m_iType); } catch(E_InetAddr e) { throw E_Socket("Unable to connect to " + strPeer + " on port "+ strPort, e); } pAddr = (struct sockaddr*)cPeerAddr.GetInetAddr(); iAddrLen = sizeof(*cPeerAddr.GetInetAddr()); }#endif else { ASSERT(false); } // Bind the socket to the local address int iRc = connect(m_hSocket, pAddr, iAddrLen); if(iRc) { throw E_Socket("Unable to connect to " + strPeer + " on port " + strPort+": " + GetErrorMsg(SYSTEM_NETWORK)); }}//------------------------------------------------------------------------------////------------------------------------------------------------------------------void C_Socket::Listen(int iBacklog){ int iRc = listen(m_hSocket, iBacklog); if(iRc) { throw E_Socket("Unable to listen for "+GetPeerName()+"/"+ GetPeerPort()+" on "+GetLocalName()+"/"+GetLocalPort()+": "+ GetErrorMsg(SYSTEM_NETWORK)); }}//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_Socket* C_Socket::Accept(){ int iRc = -1; if(m_iDomain == AF_INET) { struct sockaddr_in sPeer; socklen_t iAddrLen = sizeof(sPeer); iRc = accept(m_hSocket, (struct sockaddr*)&sPeer, &iAddrLen); }#ifdef HAVE_IPV6 else if(m_iDomain == AF_INET6) { struct sockaddr_in6 sPeer; socklen_t iAddrLen = sizeof(sPeer); iRc = accept(m_hSocket, (struct sockaddr*)&sPeer, &iAddrLen); }#endif else { ASSERT(false); } C_Socket* pSocket = NULL; if(iRc < 0) { throw E_Socket("Unable to accept connection from " + GetPeerName() + ": "+GetErrorMsg(SYSTEM_NETWORK)); } else { pSocket = new C_Socket(); pSocket->m_iDomain = m_iDomain; pSocket->m_hSocket = iRc; } return pSocket;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// This method waits for data until some are available or a signal is caught// If you want the signal safe equivalent method, call the following one with// a timeout set to 0// Returns the number of byte read or throw an exception if an error occurs//------------------------------------------------------------------------------int C_Socket::Read(char* pBuff, int iBuffLen, int iFlags){ ASSERT(pBuff); // Wait for data until something is received int iRc = recv(m_hSocket, pBuff, iBuffLen, iFlags); if(iRc < 0) { throw E_Socket("Unable to receive data: " + GetErrorMsg(SYSTEM_NETWORK)); } return iRc;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------int C_Socket::ReadTimeOut(char* pBuff, int iBuffLen, int iTimeOut, int iFlags){ ASSERT(pBuff); int iRc = NO_ERR; // Put our socket in the set of socket to monitor fd_set sSockSet; FD_ZERO(&sSockSet); FD_SET(m_hSocket, &sSockSet); // Wait up to timeout seconds struct timeval sTv; sTv.tv_sec = iTimeOut; sTv.tv_usec = 0; // Select returns with error EINTR when a signal is caught: detect it // and retry a select when this occurs do { iRc = select(m_hSocket+1, &sSockSet, NULL, NULL, &sTv); if (iRc > 0) { // Data were received before timeout iRc = recv(m_hSocket, pBuff, iBuffLen, iFlags); } else { // Reinit the sTv and sockSet structures for the next loop sTv.tv_sec = iTimeOut; sTv.tv_usec = 0; FD_ZERO(&sSockSet); FD_SET(m_hSocket, &sSockSet); } } while (iRc == -1 && GetErrorCode(SYSTEM_NETWORK) == ERR_INTR); if(iRc < 0) { throw E_Socket("Unable to receive data: "+ GetErrorMsg(SYSTEM_NETWORK)); } return iRc;}//------------------------------------------------------------------------------// //------------------------------------------------------------------------------// This method waits for data until some are available or a signal is caught// If you want the signal safe equivalent method, call the following one with// a timeout set to 0// Returns the number of byte written or throw an exception if an error occurs//------------------------------------------------------------------------------int C_Socket::Write(const char* pBuff, int iBuffLen, int iFlags){ ASSERT(pBuff); // Wait until the data could be sent int iRc = send(m_hSocket, pBuff, iBuffLen, iFlags); if(iRc < 0) { throw E_Socket("Unable to send data: " + GetErrorMsg(SYSTEM_NETWORK)); } return iRc;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------int C_Socket::Send(const C_SocketBuff& cBuffers, unsigned int iSlotCount, unsigned int iOffset){ ASSERT(iSlotCount <= cBuffers.GetSlotCount()); C_SocketBuff::sock_buff* pBuff = cBuffers.GetRawBuffers(); // Send the data contained in the buffers#ifdef STRUCT_IOVEC_IN_SYS_UIO_H int iRc = writev(m_hSocket, &pBuff[iOffset], iSlotCount);#elif defined WIN32 unsigned long count; int iRc = WSASend(m_hSocket, pBuff+iOffset, iSlotCount, &count, 0, NULL, NULL);#endif if(iRc < 0) { throw E_Socket("Unable to send data: " + GetErrorMsg(SYSTEM_NETWORK)); } return iRc;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------int C_Socket::Send(const C_SocketBuff& cBuffers){ return Send(cBuffers, cBuffers.GetSlotCount(),0);}//------------------------------------------------------------------------------////------------------------------------------------------------------------------int C_Socket::WriteTo(C_Inet4Addr& cPeerAddr, const char* pBuff, int iBuffLen, int iFlags){ ASSERT(pBuff); ASSERT(m_iDomain == AF_INET); int iRc = sendto(m_hSocket, pBuff, iBuffLen, iFlags, (const sockaddr*)cPeerAddr.GetInetAddr(), sizeof(*cPeerAddr.GetInetAddr()));/* if(iRc < 0) { throw E_Socket("Unable to send data: " + GetErrorMsg(SYSTEM_NETWORK)); }*/ return iRc;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------#ifdef HAVE_IPV6int C_Socket::WriteTo(C_Inet6Addr& cPeerAddr, const char* pBuff, int iBuffLen, int iFlags){ ASSERT(pBuff); ASSERT(m_iDomain == AF_INET6); int iRc = sendto(m_hSocket, pBuff, iBuffLen, iFlags, (const sockaddr*)cPeerAddr.GetInetAddr(), sizeof(*cPeerAddr.GetInetAddr()));/* if(iRc < 0) { throw E_Socket("Unable to send data: " + GetErrorMsg(SYSTEM_NETWORK)); }*/ return iRc;}#endif//------------------------------------------------------------------------------////------------------------------------------------------------------------------int C_Socket::SendTo(C_Inet4Addr& cPeerAddr, const C_SocketBuff& cBuffers, unsigned int iSlotCount){ // Further writing ASSERT(false); ASSERT(m_iDomain == AF_INET); int iRc = GEN_ERR; return iRc;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------int C_Socket::SendTo(C_Inet4Addr& cPeerAddr, const C_SocketBuff& cBuffers){ return SendTo(cPeerAddr, cBuffers, cBuffers.GetSlotCount());}//------------------------------------------------------------------------------////------------------------------------------------------------------------------int C_Socket::Recv(C_SocketBuff& cBuffers, unsigned int iSlotCount){ ASSERT(iSlotCount <= cBuffers.GetSlotCount());#ifdef STRUCT_IOVEC_IN_SYS_UIO_H C_SocketBuff::sock_buff* pBuff = cBuffers.GetRawBuffers(); // Read the data and put them in the buffers int iRc = readv(m_hSocket, pBuff, iSlotCount);#elif defined WIN32 ASSERT(false); int iRc = GEN_ERR;#endif if(iRc < 0) { throw E_Socket("Unable to read data: " + GetErrorMsg(SYSTEM_NETWORK)); } return iRc;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------int C_Socket::Recv(C_SocketBuff& cBuffers){ return Recv(cBuffers, cBuffers.GetSlotCount());}//------------------------------------------------------------------------------////------------------------------------------------------------------------------bool C_Socket::operator == (const C_Socket& cArg){ return cArg.m_hSocket == m_hSocket;}//------------------------------------------------------------------------------////------------------------------------------------------------------------------C_String C_Socket::GetLocalName() const{ C_String strLocalName("Unknown"); if(m_iDomain == AF_INET) { struct sockaddr_in saIntf; socklen_t iNameLen = sizeof(saIntf); int iRc = getsockname(m_hSocket, (struct sockaddr*)&saIntf, &iNameLen); ASSERT(iNameLen == sizeof(saIntf)); if(iRc) { throw E_Socket("Unable to get name of the intf: " + GetErrorMsg(SYSTEM_NETWORK)); } else strLocalName = inet_ntoa(saIntf.sin_addr); }#ifdef HAVE_IPV6 else if(m_iDomain == AF_INET6) { struct sockaddr_in6 saIntf; socklen_t iNameLen = sizeof(saIntf); int iRc = getsockname(m_hSocket, (struct sockaddr*)&saIntf, &iNameLen); ASSERT(iNameLen == sizeof(saIntf)); if(iRc) { throw E_Socket("Unable to get name of the intf: " + GetErrorMsg(SYSTEM_NETWORK)); } else { char pszDst[40]; // 40 characters is enough for an IPv6 address if(inet_ntop(AF_INET6, &saIntf.sin6_addr, pszDst, 40) == pszDst)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -