TCPSocket::TCPSocket( Socket socket, IPv4Address destination ) : TCPSocket::TCPSocket( ) { m_Socket = socket; m_Destination = destination; m_Connected = true; SetBlockingMode( false ); SetNoDelay(); }
status_t TFTPClient::Connect(const char *address, uint16 port) { int err; struct sockaddr_in addr; memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_len = sizeof(struct sockaddr_in); addr.sin_family = AF_INET; addr.sin_port = htons(port); if (inet_aton(address, &addr.sin_addr) == 0) { struct hostent *host = gethostbyname(address); if (!host) { err = h_errno; fStrError.SetTo(hstrerror(err)); return err; } addr.sin_addr = *(struct in_addr *)host->h_addr; } fprintf(stderr, "Connecting %u.%u.%u.%u : %u\n", ((uint8 *)&addr.sin_addr.s_addr)[0], ((uint8 *)&addr.sin_addr.s_addr)[1], ((uint8 *)&addr.sin_addr.s_addr)[2], ((uint8 *)&addr.sin_addr.s_addr)[3], port); if (fControlEndpoint != -1) Disconnect(); fControlEndpoint = socket(AF_INET, SOCK_STREAM, 0); if (fControlEndpoint == -1) { err = errno; fStrError.SetTo(strerror(err)); return err; } // non-blocking mode if ((err = SetBlockingMode(false)) != B_OK) return err; // connect if (connect(fControlEndpoint, (struct sockaddr *)&addr, sizeof(addr)) != 0) { err = errno; fStrError.SetTo(strerror(err)); if ((err != 0) && (err != EISCONN) && (err != EINPROGRESS) && (err != EALREADY)) return err; } // blocking mode // if ((err = SetBlockingMode(true)) != B_OK) return err; // snooze(500000); // 受信スレッド開始 err = resume_thread(fReceiverThreadID); return err; }
bool TCPSocket::Connect( const IPv4Address& destination ) { //Set up the socket m_Socket = static_cast< int >( socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ); // Adress Family = INET and the protocol to be used is TCP if ( m_Socket <= 0 ) { LogErrorMessage( "Failed to create socket", "TCPSocket" ); return false; } SetBlockingMode( false ); // Try to connect Logger::Log( "Attempting to connect to " + destination.GetPrintableAddressAndPort(), "TCPSocket", LogSeverity::INFO_MSG ); sockaddr_in addr = destination.GetSockAddr(); timeval timeOut; timeOut.tv_sec = CONNECTION_TIMEOUT_SECONDS; timeOut.tv_usec = 0; fd_set set; FD_ZERO( &set ); FD_SET( m_Socket, &set ); int returnVal; if ( ( returnVal = connect( m_Socket, ( sockaddr * )&addr, sizeof( sockaddr_in ) ) ) == INVALID_SOCKET ) { if ( !SHOULD_WAIT_FOR_TIMEOUT ) return false; } returnVal = select( static_cast<int>( m_Socket + 1 ), NULL, &set, NULL, &timeOut ); if ( returnVal > 0 ) // A socket was connected { m_Destination = destination; m_Connected = true; SetNoDelay(); Logger::Log( "Connection attempt to " + destination.GetPrintableAddressAndPort() + " was successfull!", "TCPSocket", LogSeverity::INFO_MSG ); return true; } else if ( returnVal == 0 ) { Logger::Log( "Connection attempt to " + destination.GetPrintableAddressAndPort() + " timed out", "TCPSocket", LogSeverity::INFO_MSG ); return false; } else { LogErrorMessage( "Connection attempt to " + destination.GetPrintableAddressAndPort() + " failed", "TCPSocket" ); return false; } }
/*********************************************** Connect Connects to a specified port Params port - port to connect to address - address to connect to (ex."204.64.75.73") [timeout] - time to wait for connection [family] - protocol family: AF_INET, AF_AF_IPX, etc. Default AF_INET [sockType] - SOCK_STREAM (TCP) or SOCK_DGRAM (UDP) Default is SOCK_STREAM Return UTE_SOCK_ALREADY_OPEN - socket already open or in use UTE_SOCK_CREATE_FAILED - socket creation failed UTE_SOCK_CONNECT_FAILED - socket connection failed UTE_INVALID_ADDRESS - invalid address UTE_SUCCESS - success UTE_CONNECT_TIMEOUT - connect time out ************************************************/ int CUT_WSThread::Connect(unsigned int port, LPCSTR address, long timeout, int family, int sockType) { int nError = UTE_SUCCESS; if(m_clientSocket != INVALID_SOCKET) return OnError(UTE_SOCK_ALREADY_OPEN); //copy the params //check to see if the domain is a name or address if (inet_addr(address) == INADDR_NONE){ if(GetAddressFromName(address, m_szAddress, sizeof(m_szAddress)) != UTE_SUCCESS) return OnError(UTE_INVALID_ADDRESS); } else strncpy(m_szAddress, address, sizeof(m_szAddress)); //m_nFamily = family; m_nSockType = sockType; //Set up the SockAddr structure memset(&m_clientSocketAddr, 0, sizeof(m_clientSocketAddr)); //clear all m_clientSocketAddr.sin_port = (unsigned short) htons((u_short )port); //port m_clientSocketAddr.sin_family = (short) family; //family m_clientSocketAddr.sin_addr.s_addr = inet_addr(m_szAddress); //address //create a socket m_clientSocket = socket(family, sockType, 0); if(m_clientSocket == INVALID_SOCKET) return OnError(UTE_SOCK_CREATE_FAILED); // switch to nonblocking mode to support timeout if(timeout >= 0) SetBlockingMode(CUT_NONBLOCKING); if( connect(m_clientSocket,(LPSOCKADDR)&m_clientSocketAddr,sizeof(m_clientSocketAddr))==SOCKET_ERROR){ if(WSAGetLastError() == WSAEWOULDBLOCK ) { if(timeout >= 0) { if(WaitForSend(timeout, 0) != CUT_SUCCESS) { SocketClose(m_clientSocket); m_clientSocket = INVALID_SOCKET; return OnError(UTE_CONNECT_TIMEOUT); } SetBlockingMode(CUT_BLOCKING); } //set up the default send are receive time-outs // SetReceiveTimeOut(m_lRecvTimeOut); // SetSendTimeOut(m_lSendTimeOut); // save the remote port // m_nRemotePort = ntohs(m_clientSocketAddr.sin_port); // save the local port SOCKADDR_IN sa; int len = sizeof(SOCKADDR_IN); getsockname(m_clientSocket, (SOCKADDR*) &sa, &len); // m_nLocalPort = ntohs(sa.sin_port); // Call socket connection notification if((nError = SocketOnConnected(m_clientSocket, address)) != UTE_SUCCESS) { SocketClose(m_clientSocket); m_clientSocket = INVALID_SOCKET; } return OnError(nError); } else { // did not have these two lines prior to Feb 11 1999 SocketClose(m_clientSocket); m_clientSocket = INVALID_SOCKET; } return OnError(UTE_SOCK_CONNECT_FAILED); // ERROR: connect unsuccessful } // set up the default send are receive time-outs // SetReceiveTimeOut(m_lRecvTimeOut); SetSendTimeOut(m_lSendTimeOut); // Call socket connection notification if((nError = SocketOnConnected(m_clientSocket, address)) != UTE_SUCCESS) { SocketClose(m_clientSocket); m_clientSocket = INVALID_SOCKET; } return OnError(nError); }
/*************************************************** IsConnected This function checks to see if the client is still currently connected Params none Return TRUE - if the client is still connected FALSE - if the client has disconnected ****************************************************/ BOOL CUT_WSThread::IsConnected(){ int rt1, rt2, error; fd_set readSet; struct timeval tv; tv.tv_sec = 0; // do not block - for polling tv.tv_usec = 0; FD_ZERO(&readSet); // always reinit //This will generate a warning // this is internal to winsock (warning C4127: conditional expression is constant) // maybe you want to use // #pragma warning (disable : 4127) // but on the other hand maybe you don't #pragma warning( disable : 4127 ) FD_SET(m_clientSocket,&readSet); #pragma warning( default : 4127 ) rt1 = select(-1,&readSet,NULL,NULL,&tv); if(SOCKET_ERROR == rt1) { int err = WSAGetLastError(); switch (err) { case WSANOTINITIALISED: case WSAENETDOWN: case WSAENOTSOCK: return FALSE; break; default: break; } // other possible errors: } // WSAEFAULT - WSAEINVAL - WSAEINTR(ws1.1) char data = 0; SetBlockingMode(CUT_NONBLOCKING); //no blocking // the security version of Ultimate TCP/IP uses diffrent implemnation // of Receive and in order to avoid calling it's error checking we will call the base // winsock recv // if you use your own class or stream for using you can either // change this code to call your own receive function // or expose recv function of your base class that will fulfil this // recv function requirment rt2 = recv(m_clientSocket,(char *)&data,1, MSG_PEEK); if(rt2 == SOCKET_ERROR){ error = WSAGetLastError(); switch(error) { case WSAEWOULDBLOCK: SetBlockingMode(CUT_BLOCKING); // back to blocking mode rt2 = 0; // no data - set rt2 to 0 and continue // Alternative - use a small // timeout value in tv .... break; case WSAECONNRESET: SetBlockingMode(CUT_BLOCKING); // back to blocking mode return FALSE; break; case WSAEINPROGRESS: SetBlockingMode(CUT_BLOCKING); // back to blocking mode return TRUE; break; case WSAESHUTDOWN: case WSAENETDOWN: case WSAENETRESET: case WSAETIMEDOUT: return FALSE; break; case WSAEISCONN: case WSAENOTSOCK: case WSAEFAULT: case WSAEINTR: case WSAEINVAL: case WSAEOPNOTSUPP: case WSAEMSGSIZE: return FALSE; break; default: break; // should never happen. } } SetBlockingMode(CUT_BLOCKING); //blocking // final check - if we made it through the recv, we know the connection // was not reset (RST) - but no error will show if the remote has initiated // a graceful close (FIN). // the select with readfds will return with 1 (rt1) if data is available or // the close is in progress. The call to recv will be 0 if no data // waiting, so we examine rt1 and rt2 together to determine closure. // For protocols using WSASendDisconnect() this behavior may need to be // reexamined. if(0 == rt2 && 1 == rt1) return FALSE; return TRUE; }