int _ossSocket::bind_listen () { int rc = EDB_OK ; int temp = 1 ; rc = setsockopt ( _fd, SOL_SOCKET, SO_REUSEADDR, (char*)&temp, sizeof(int) ) ; if ( rc ) { PD_LOG ( PDWARNING, "Failed to setsockopt SO_REUSEADDR, rc = %d", SOCKET_GETLASTERROR ) ; } rc = setSocketLi ( 1, 30 ) ; if ( rc ) { PD_LOG ( PDWARNING, "Failed to setsockopt SO_LINGER, rc = %d", SOCKET_GETLASTERROR ) ; } rc = ::bind ( _fd, (struct sockaddr*)&_sockAddress, _addressLen ) ; if ( rc ) { PD_RC_CHECK( EDB_NETWORK, PDERROR, "Failed to bind socket, rc = %d", SOCKET_GETLASTERROR ) ; } rc = listen ( _fd, SOMAXCONN ) ; if ( rc ) { PD_RC_CHECK( EDB_NETWORK, PDERROR, "Failed to listen socket, rc = %d", SOCKET_GETLASTERROR ) ; } done : return rc ; error : close () ; goto done ; }
// PD_TRACE_DECLARE_FUNCTION ( SDB_OSSSK_BIND_LSTN, "ossSocket::bind_listen" ) INT32 _ossSocket::bind_listen () { INT32 rc = SDB_OK ; PD_TRACE_ENTRY ( SDB_OSSSK_BIND_LSTN ); INT32 temp = 1 ; SDB_ASSERT ( _init, "socket is not initialized" ) ; PD_CHECK( _init, SDB_SYS, error, PDWARNING, "Socket is not init" ) ; rc = setsockopt ( _fd, SOL_SOCKET, SO_REUSEADDR, (char*)&temp, sizeof (INT32) ) ; if ( rc ) { PD_LOG ( PDWARNING, "Failed to setsockopt SO_REUSEADDR, rc = %d", SOCKET_GETLASTERROR ) ; } rc = setSocketLi( 1, 30 ) ; if ( rc ) { PD_LOG ( PDWARNING, "Failed to setsockopt SO_LINGER, rc = %d", SOCKET_GETLASTERROR ) ; } rc = ::bind ( _fd, (struct sockaddr *)&_sockAddress, _addressLen ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to bind socket, rc = %d", SOCKET_GETLASTERROR ) ; rc = SDB_NETWORK ; goto error ; } rc = listen ( _fd, SOMAXCONN ) ; if ( rc ) { PD_LOG ( PDERROR, "Failed to listen socket, rc = %d", SOCKET_GETLASTERROR ) ; rc = SDB_NETWORK ; goto error ; } done : PD_TRACE_EXITRC ( SDB_OSSSK_BIND_LSTN, rc ); return rc ; error : close () ; goto done ; }
int ossSocket::bind_listen() { int rc = EDB_OK; int temp = 1; //确保sock可以重复使用SO_REUSEADDR /* 这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端 口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息,指明"地址 已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧使用同一端口,此时 SO_REUSEADDR 选项非常有用。 */ rc = setsockopt(_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&temp, sizeof(int)); if(rc) { printf("Failed to setsockopt SO_REUSEADDR,rc=%d", SOCKET_GETLASTERROR); } rc = setSocketLi(1, 30); if(rc) { printf("Failed to setsockopt SO_LINGER, rc=%d", SOCKET_GETLASTERROR); } //将套接字绑定到本地地址 rc = ::bind(_fd, (struct sockaddr*)&_sockAddress, _addressLen); if(rc) { printf("Failed to bind socket, rc=%d", SOCKET_GETLASTERROR); rc=EDB_NETWORK; goto error; } //为避免协议拒绝或丢弃传入的请求,把来不及处理的请求排队,至多将SOMAXCONN个连接请求排队 rc = listen(_fd, SOMAXCONN); if(rc) { printf("Failed to listen socket, rc=%d", SOCKET_GETLASTERROR); rc = EDB_NETWORK; goto error; } done: return rc; error: close(); goto done; }