void UdpSocket::CreateConnection() { #ifdef ENABLE_IPV6 #ifdef IPPROTO_IPV6 if (IsIpv6()) { if (GetSocket() == INVALID_SOCKET) { SOCKET s = CreateSocket(AF_INET6, SOCK_DGRAM, "udp"); if (s == INVALID_SOCKET) { return; } SetNonblocking(true, s); Attach(s); } return; } #endif #endif if (GetSocket() == INVALID_SOCKET) { SOCKET s = CreateSocket(AF_INET, SOCK_DGRAM, "udp"); if (s == INVALID_SOCKET) { return; } SetNonblocking(true, s); Attach(s); } }
void addfd(int epollfd,int fd,bool enable_ET) { epoll_event event; /* struct epoll_event { uint32_t events; [> Epoll events <] epoll_data_t data; [> User data variable <] } __EPOLL_PACKE typedef union epoll_data { void *ptr; int fd; uint32_t u32; uint64_t u64; } epoll_data_t; */ event.data.fd = fd; event.events = EPOLLIN; if(enable_ET) { event.events |=EPOLLET; } epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&event); SetNonblocking(fd); }
int UdpSocket::Bind(SocketAddress& ad, int range) { if (GetSocket() == INVALID_SOCKET) { Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp")); } if (GetSocket() != INVALID_SOCKET) { SetNonblocking(true); int n = bind(GetSocket(), ad, ad); int tries = range; while (n == -1 && tries--) { ad.SetPort(ad.GetPort() + 1); n = bind(GetSocket(), ad, ad); } if (n == -1) { Handler().LogError(this, "bind", Errno, StrError(Errno), LOG_LEVEL_FATAL); SetCloseAndDelete(); #ifdef ENABLE_EXCEPTIONS throw Exception("bind() failed for UdpSocket, port:range: " + Utility::l2string(ad.GetPort()) + ":" + Utility::l2string(range)); #endif return -1; } m_bind_ok = true; m_port = ad.GetPort(); return 0; } return -1; }
int SelectHandle(const int listenfd) { int connectfd = -1; fd_set rset; int nready = 0; int err = 0; struct sockaddr_in clientaddr; socklen_t socklen = sizeof(clientaddr); while(1) { FD_ZERO(&rset); FD_SET(listenfd,&rset); nready = select(listenfd+1,&rset,NULL,NULL,NULL); if (nready < 0) { if (errno == EINTR) { continue; } err = errno; printf("select(),error:%s\n",strerror(errno)); break; } if (FD_ISSET(listenfd,&rset)) { connectfd = accept(listenfd,(struct sockaddr*)&clientaddr,&socklen); if (connectfd < 0) { err = errno; printf("accept(),error:%s\n",strerror(errno)); continue; } else { printf("accept client from %s:%d \n",inet_ntoa(clientaddr.sin_addr),clientaddr.sin_port); err = SetNonblocking(connectfd); if (0 != err) { err = errno; printf("SetNonblocking(),error:%s\n",strerror(errno)); break; } } } err = ConnectSocketHandle(connectfd); if (err != 0) { printf("ConnectSocketHandle(),error:%s\n",strerror(errno)); break; } if (connectfd != -1) { close(connectfd); } } }
void UdpSocket::SendToBuf(SocketAddress& ad, const char *data, int len, int flags) { if (GetSocket() == INVALID_SOCKET) { Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp")); } if (GetSocket() != INVALID_SOCKET) { SetNonblocking(true); if ((m_last_size_written = sendto(GetSocket(), data, len, flags, ad, ad)) == -1) { Handler().LogError(this, "sendto", Errno, StrError(Errno), LOG_LEVEL_ERROR); } } }
bool UdpSocket::Open(SocketAddress& ad) { if (GetSocket() == INVALID_SOCKET) { Attach(CreateSocket(ad.GetFamily(), SOCK_DGRAM, "udp")); } if (GetSocket() != INVALID_SOCKET) { SetNonblocking(true); if (connect(GetSocket(), ad, ad) == -1) { Handler().LogError(this, "connect", Errno, StrError(Errno), LOG_LEVEL_FATAL); SetCloseAndDelete(); return false; } SetConnected(); return true; } return false; }
int SctpSocket::Open(SocketAddress& ad) { if (!ad.IsValid()) { Handler().LogError(this, "SctpSocket", -1, "invalid address", LOG_LEVEL_ERROR); return -1; } if (GetSocket() == INVALID_SOCKET) { Attach(CreateSocket(ad.GetFamily(), m_type, "sctp")); } if (GetSocket() != INVALID_SOCKET) { if (!SetNonblocking(true)) { return -1; } int n = connect(GetSocket(), ad, ad); if (n == -1) { // check error code that means a connect is in progress #ifdef _WIN32 if (Errno == WSAEWOULDBLOCK) #else if (Errno == EINPROGRESS) #endif { Handler().LogError(this, "connect: connection pending", Errno, StrError(Errno), LOG_LEVEL_INFO); SetConnecting( true ); // this flag will control fd_set's } else { Handler().LogError(this, "SctpSocket", -1, "connect() failed", LOG_LEVEL_ERROR); } } return n; } return -1; }
int NetClient::CreateSocket(bool usingtcp /* = false */) { do { int typ = usingtcp ? SOCK_STREAM : SOCK_DGRAM; int fd = socket(AF_INET, typ, 0); if (fd < 0) break; if (usingtcp) { int val = 1; setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char *)&val, sizeof(val)); //setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const char *)&val, sizeof(val)); } else { int buf_size = 65535; setsockopt ( fd, SOL_SOCKET, SO_RCVBUF, ( const char * ) &buf_size, sizeof ( buf_size ) ); setsockopt ( fd, SOL_SOCKET, SO_SNDBUF, ( const char * ) &buf_size, sizeof ( buf_size ) ); } #ifndef WIN32 //recv timeout struct timeval timeout={15,0};//15s setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)); #endif #ifdef IOS int set = 1; setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); #endif if (!SetNonblocking(fd, true)) { close_socket(fd); break; } return fd; } while (0); return INVALID_SOCKET; }
bool TcpSocket::Open(SocketAddress& ad,SocketAddress& bind_ad,bool skip_socks) { if (!ad.IsValid()) { Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL); SetCloseAndDelete(); return false; } if (Handler().GetCount() >= Handler().MaxCount()) { Handler().LogError(this, "Open", 0, "no space left for more sockets", LOG_LEVEL_FATAL); SetCloseAndDelete(); return false; } SetConnecting(false); #ifdef ENABLE_SOCKS4 SetSocks4(false); #endif // check for pooling #ifdef ENABLE_POOL if (Handler().PoolEnabled()) { ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad); if (pools) { CopyConnection( pools ); delete pools; SetIsClient(); SetCallOnConnect(); // ISocketHandler must call OnConnect Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO); return true; } } #endif // if not, create new connection SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp"); if (s == INVALID_SOCKET) { return false; } // socket must be nonblocking for async connect if (!SetNonblocking(true, s)) { SetCloseAndDelete(); closesocket(s); return false; } #ifdef ENABLE_POOL SetIsClient(); // client because we connect #endif SetClientRemoteAddress(ad); int n = 0; if (bind_ad.GetPort() != 0) { bind(s, bind_ad, bind_ad); } #ifdef ENABLE_SOCKS4 if (!skip_socks && GetSocks4Host() && GetSocks4Port()) { Ipv4Address sa(GetSocks4Host(), GetSocks4Port()); { std::string sockshost; Utility::l2ip(GetSocks4Host(), sockshost); Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" + Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO); } SetSocks4(); n = connect(s, sa, sa); SetRemoteAddress(sa); } else #endif { n = connect(s, ad, ad); SetRemoteAddress(ad); } if (n == -1) { // check error code that means a connect is in progress #ifdef _WIN32 if (Errno == WSAEWOULDBLOCK) #else if (Errno == EINPROGRESS) #endif { Attach(s); SetConnecting( true ); // this flag will control fd_set's } else #ifdef ENABLE_SOCKS4 if (Socks4() && Handler().Socks4TryDirect() ) // retry { closesocket(s); return Open(ad, true); } else #endif #ifdef ENABLE_RECONNECT if (Reconnect()) { Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO); Attach(s); SetConnecting( true ); // this flag will control fd_set's } else #endif { Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL); SetCloseAndDelete(); closesocket(s); return false; } } else { Attach(s); SetCallOnConnect(); // ISocketHandler must call OnConnect } // 'true' means connected or connecting(not yet connected) // 'false' means something failed return true; //!Connecting(); }
static void on_accept(int sock,short event,void *arg) { Proxyer* pserver = (Proxyer*) arg; int clientsocket = -1; int remotesocket = -1; Context* newcontext = NULL; int err = 0; struct sockaddr_in client_addr,remote_addr; socklen_t len = sizeof(client_addr); do { clientsocket = accept(sock,(struct sockaddr *)&client_addr,&len); if ( -1 == clientsocket ) { std::cerr<<"accept client failed! err: "<<strerror(errno)<<std::endl; break; } std::cout<<"receive connection "<<GetPeerInfo(&client_addr)<<std::endl; err = SetNonblocking(clientsocket); if ( 0 != err ) { std::cerr<<"set nonblocking for client socket failed! err: "<<strerror(err)<<std::endl; break; } remotesocket = socket(AF_INET,SOCK_STREAM,0); if ( -1 == remotesocket ) { std::cerr<<"create remote socket failed!"<<std::endl; break; } memset(&remote_addr,0,sizeof(remote_addr)); remote_addr.sin_family = AF_INET; remote_addr.sin_port = htons(pserver->remote_port); remote_addr.sin_addr.s_addr = inet_addr(pserver->remote_addr.c_str()); err = connect(remotesocket,(struct sockaddr*)&remote_addr,sizeof(remote_addr)); if ( 0 != err ) { if ( EINPROGRESS != err ) { err = errno; std::cerr<<"connect remote failed! err: "<<strerror(err)<<std::endl; break; } err = CheckConnect(remotesocket); if ( 0 != err ) { err = errno; std::cerr<<"connect remote failed! err: "<<strerror(err)<<std::endl; break; } std::cout<<"connect remote success!"<<std::endl; } else { std::cout<<"connect remote success!"<<std::endl; } /** * connect remote success,then we need to create a Context * */ newcontext = new Context(pserver,clientsocket,remotesocket); if ( NULL == newcontext ) { std::cerr<<"Alloc Context failed!"<<std::endl; break; } err = newcontext->Init(); if ( 0 != err ) { std::cerr<<"newcontext init failed!"<<std::endl; break; } /** * 将context添加到server的队列中 * */ pserver->m_context_list.push_back(newcontext); } while(0); do{ if ( 0 != err ) { if ( -1 == clientsocket ) { break; } close(clientsocket); if ( -1 == remotesocket ) { break; } close(remotesocket); if ( NULL == newcontext ) { break; } delete newcontext; } } while(0); }
int EventLoop::AddEvent(IOEvent *e) { e->el_ = this; SetNonblocking(e->fd_); return SetEvent(e, EPOLL_CTL_ADD); }
int main(int argc,char *argv[]) { int listenfd; int serverPort = 8888; struct sockaddr_in serveraddr; int nread = 0; int nwrite = 0; int err = 0; int ret = 0; socklen_t socklen = sizeof(serveraddr); do{ listenfd = socket(AF_INET,SOCK_STREAM,0); if (listenfd < 0) { err = errno; printf("socket(),error:%s\n",strerror(errno)); break; } int opt = 1; if (setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)) < 0) { err = errno; printf("setsockopt(),error:%s\n",strerror(errno)); break; } bzero(&serveraddr,sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = INADDR_ANY; serveraddr.sin_port = htons(8888); ret = bind(listenfd,(struct sockaddr*)&serveraddr,socklen); if (ret < 0) { err = errno; printf("bind(),error:%s\n",strerror(errno)); break; } ret = listen(listenfd,1024); if (ret < 0) { err = errno; printf("listen(),error:%s\n",strerror(errno)); break; } err = SetNonblocking(listenfd); if (0 != err) { err = errno; printf("setnonblockint(),error:%s\n",strerror(errno)); break; } printf("server startup,listen on port 8888!\n"); err = SelectHandle(listenfd); if (0 != err) { printf("SelectHandle(),error:%s\n",strerror(errno)); break; } } while(0); if (-1 != listenfd) { close(listenfd); } return err; }