int CTCPSocket::connectServer() { g_insLogMng.debug("socket", CLogMng::LogMode2, "Begin to connect to server......"); m_iFd = socket(AF_INET, SOCK_STREAM, 0); if( m_iFd <= 0) { g_insLogMng.error( "socket(AF_INET, SOCK_STREAM, 0) for %s failed, m_iFd = %d", m_sIP); return -1; } //g_insLogMng.runlog("Create:fd=%d;ip=%s", m_iFd, m_sIP); g_insLogMng.debug("socket", CLogMng::LogMode2, "Create fd = %d for connect (%s) successfully.", m_iFd, m_sIP); struct sockaddr_in stInAddr; memset(&stInAddr,0,sizeof(stInAddr)); stInAddr.sin_family = AF_INET; //family stInAddr.sin_port = htons(m_iPort); //port struct in_addr tmpAddr; //inet_aton() converts the Internet host address cp from the standard num- //bers-and-dots notation into binary data and stores it in the structure //that inp points to. inet_aton returns nonzero if the address is valid, //zero if not. if (0 == inet_aton(m_sIP, &tmpAddr)) { g_insLogMng.debug("socket", CLogMng::LogMode2, "Connect to server failed, server IP(%s) is invalid.", m_sIP); closeSocket(); // kevinliu add 06-06 return -1; } stInAddr.sin_addr = tmpAddr; //ip //建立非阻塞方式,目的是connect超时可控制,完成后恢复 if (0 != setBlockMode(NonBlock)) { g_insLogMng.debug("socket", CLogMng::LogMode2, "Connect to server failed, setBlockMode NonBlock failed."); closeSocket(); // kevinliu add 06-06 return -1; } int iRet = connect(m_iFd, (struct sockaddr*)&stInAddr, sizeof(stInAddr)); if(iRet < 0) { g_insLogMng.debug("socket", CLogMng::LogMode2, "Connect to server(%s) error.errno=%d, %s", m_sIP, errno, strerror(errno)); if (errno != EINPROGRESS && errno != EALREADY // in process //delete && errno != EINTR && errno != EAGAIN) // try again { g_insLogMng.error( "Connect to server(%s) error.errno=%d, %s", m_sIP, errno, strerror(errno)); closeSocket(); return -1; } else // 其他的再尝试检查端口的状态 { if ( 0 > checkSocket(g_insConfigMng.m_tComCfg.m_iRecvMsgTimeout, CTCPSocket::WriteMode)) { g_insLogMng.error("Connect to Server(%s) failed, checksocket timeout.", m_sIP); closeSocket(); return -1; } } } //恢复回阻塞方式 if (0 != setBlockMode(Block)) { g_insLogMng.debug("socket", CLogMng::LogMode2, "Connect to server failed, recover setBlockMode Block failed."); closeSocket(); return -1; } // Check if there were any error 这一块应该没有太大作用,去掉 /* int err; socklen_t err_len = sizeof(int); int ret = getsockopt(m_iFd, SOL_SOCKET,SO_ERROR,&err,&err_len); if(ret < 0) { g_insLogMng.error("getsockopt return -1"); closeSocket(); return -1; } if(err > 0) { g_insLogMng.error("getsockopt return error"); closeSocket(); return -1; } */ g_insLogMng.debug("socket", CLogMng::LogMode1, "Connect to server(%s) successfully, fd = %d", m_sIP, m_iFd); return 0; }
int CTCPSocket::createSocket() { g_insLogMng.normal("Begin to create socket server(%s, %d)......", m_sIP, m_iPort); int iRet = 0; int iReuseAddr = 1; struct sockaddr_in insAddress; memset((char *) &insAddress, 0, sizeof(insAddress)); insAddress.sin_family = AF_INET; insAddress.sin_port = htons(m_iPort); if (0 != strcmp(m_sIP, "ALL") && 0 != strcmp(m_sIP, "all") ) { inet_aton(m_sIP, &insAddress.sin_addr); } else { insAddress.sin_addr.s_addr = htonl(INADDR_ANY); } // 生成 fd m_iFd = socket(AF_INET, SOCK_STREAM, 0); if (m_iFd < 0) { g_insLogMng.error("Create: socket() failed, errno = %d, reason = %s", errno, strerror(errno)); return -1; } g_insLogMng.debug("socket", CLogMng::LogMode1, "Create socket id successfully, fd = %d", m_iFd); //可复用 setsockopt(m_iFd, SOL_SOCKET, SO_REUSEADDR, (void*)(&(iReuseAddr)), sizeof(iReuseAddr)); g_insLogMng.debug("socket", CLogMng::LogMode3, "Setsockopt successfully."); if (bind(m_iFd, (struct sockaddr *) &insAddress, sizeof(insAddress)) < 0) { g_insLogMng.error("Create: bind() failed, errno = %d, reason = %s", errno, strerror(errno)); closeSocket(); return -1; } g_insLogMng.debug("socket", CLogMng::LogMode3, "Bind successfully."); /* Queue up to Max connections before having them automatically rejected. */ int iTmpNrOfCnt; if ( 0 != g_insConfigMng.m_tComCfg.m_iMaxNrOfCnt) { iTmpNrOfCnt = 10000; } else { iTmpNrOfCnt = g_insConfigMng.m_tComCfg.m_iMaxNrOfCnt + 10; //多余10个缓冲 } // listen iRet = listen(m_iFd, iTmpNrOfCnt); if (iRet == -1) { g_insLogMng.error("Create: listen() failed, errno = %d, reason = %s", errno, strerror(errno)); closeSocket(); return -1; } g_insLogMng.debug("socket", CLogMng::LogMode3, "Listen(maxcnt = %d) successfully.", iTmpNrOfCnt); //non block if (0 != setBlockMode(NonBlock)) { g_insLogMng.error("Create: setNonBlocking() failed, errno = %d, reason = %s", errno, strerror(errno)); closeSocket(); return -1; } //设置socket句柄的tcpcork属性 int on = 1; setsockopt (m_iFd, SOL_TCP, TCP_CORK, &on, sizeof (on)); int nSendBuf=100*1024;//设置为100K setsockopt(m_iFd, SOL_SOCKET, SO_SNDBUF, (const char*)&nSendBuf, sizeof(int)); g_insLogMng.debug("socket", CLogMng::LogMode3, "Set nonblock successfully."); g_insLogMng.normal("Create socket server(%s, %d) successfully", m_sIP, m_iPort); return 0; }
void TcpSocketImpl::connect(struct addrinfo * paddr, const char * host, const char * port, int timeout) { assert(-1 == sock); sock = HdfsSystem::socket(paddr->ai_family, paddr->ai_socktype, paddr->ai_protocol); if (-1 == sock) { THROW(HdfsNetworkException, "Create socket failed when connect to %s: %s", remoteAddr.c_str(), GetSystemErrorInfo(errno)); } if (lingerTimeout >= 0) { setLingerTimeoutInternal(lingerTimeout); } #ifdef __linux__ /* * on linux some kernel use SO_SNDTIMEO as connect timeout. * It is OK to set a very large value here since the user has its own timeout mechanism. */ setSendTimeout(3600000); #endif try { setBlockMode(false); disableSigPipe(); int rc = 0; do { rc = HdfsSystem::connect(sock, paddr->ai_addr, paddr->ai_addrlen); } while (rc < 0 && EINTR == errno && !CheckOperationCanceled()); if (rc < 0) { if (EINPROGRESS != errno && EWOULDBLOCK != errno) { if (ETIMEDOUT == errno) { THROW(HdfsTimeoutException, "Connect to \"%s:%s\" timeout", host, port); } else { THROW(HdfsNetworkConnectException, "Connect to \"%s:%s\" failed: %s", host, port, GetSystemErrorInfo(errno)); } } if (!poll(false, true, timeout)) { THROW(HdfsTimeoutException, "Connect to \"%s:%s\" timeout", host, port); } struct sockaddr peer; unsigned int len = sizeof(peer); memset(&peer, 0, sizeof(peer)); if (HdfsSystem::getpeername(sock, &peer, &len)) { /* * connect failed, find out the error info. */ char c; rc = HdfsSystem::recv(sock, &c, 1, 0); assert(rc < 0); if (ETIMEDOUT == errno) { THROW(HdfsTimeoutException, "Connect to \"%s:%s\" timeout", host, port); } THROW(HdfsNetworkConnectException, "Connect to \"%s:%s\" failed: %s", host, port, GetSystemErrorInfo(errno)); } } setBlockMode(true); } catch (...) { close(); throw; } }