int __cdecl SocketPosixC__Create(int/*boolean*/ reliable) { int one = 1; int fd = socket(AF_INET, reliable ? SOCK_STREAM : SOCK_DGRAM, 0); if (fd == -1) { Exception e = Unexpected; switch (GetSocketError()) { #ifdef _WIN32 case WSAEMFILE: #else case EMFILE: case ENFILE: #endif e = NoResources; break; } IOError(e); } #ifndef _WIN32 MakeNonBlocking(fd); #endif setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); return fd; }
bool tconn::StartListen() { sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd<0) { ERROR("create socket fail|%d|%s",errno,strerror(errno)); return false; } int nodelay=1; if(setsockopt(sockfd,SOL_TCP,TCP_NODELAY,&nodelay,sizeof(int))<0) { ERROR("set socket tcp_nodelay option fail|%d|%s",errno,strerror(errno)); return(false); } int reuse=1; if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1) { ERROR("set socket so_reuseaddr fail|%d|%s",errno,strerror(errno)); return false; } if(!MakeNonBlocking(sockfd)) return false; struct sockaddr_in svraddr; memset(&svraddr,0,sizeof(sockaddr_in)); svraddr.sin_port=htons(SERVER_PORT);//需要转换为网络编码. svraddr.sin_family=AF_INET; svraddr.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(sockfd,(struct sockaddr*)&svraddr,sizeof(svraddr))<0) { ERROR("bind fail|%x|%u|%d|%s",svraddr.sin_addr.s_addr,ntohl(svraddr.sin_port),errno,strerror(errno)); return false; } if(listen(sockfd,4096)<0) { ERROR("listen fail:%d|%s",errno,strerror(errno)); return false; } epollfd=epoll_create(EPOLL_MAX_FD_NUM); struct epoll_event event; event.events=EPOLLIN; event.data.u32=EPOLL_LISTEN_POS; if(epoll_ctl(epollfd,EPOLL_CTL_ADD,sockfd,&event)!=0) { ERROR("epoll_ctrl fail %d|%s",errno,strerror(errno)); return false; } INFO("INIT success,epollfd:%d",epollfd) ; return true; }
static void InitStream(int fd) { /* We assume that the runtime ignores SIGPIPE signals. */ int one = 1; #ifdef _WIN32 struct linger linger = {0, 0}; #else struct linger linger = {1, 1}; #endif /***** setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &SysSendBufSize, sizeof(SysSendBufSize)); setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &SysRcvBufSize, sizeof(SysRcvBufSize)); ******/ setsockopt(fd, SOL_SOCKET, SO_LINGER, &linger, sizeof(linger)); setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one)); MakeNonBlocking(fd); }
/** @brief Connects to a server on a given ip and port. * @param ip The IP address to connect to. * @param port The port number. */ void Jatta::Network::SocketTCP::Connect(const IPAddress& ip, unsigned short port) { // Check that the IP is valid if (!ip.IsValid()) { throw NetworkException(NetworkExceptionCode::FAILED_CONNECT, NetworkExceptionReason::ADDRESS_INVALID); } // Create a hints variable used to determine the connection configuration. struct addrinfo hints; memset(&hints, 0, sizeof(addrinfo)); // Check if the IP is an IPv4 or IPv6. if (ip.GetType() == IPAddressType::IPV4) { // Use IPv4. hints.ai_family = AF_INET; } else { // Use IPv6. hints.ai_family = AF_INET6; } // We're setting up a TCP/IP connection, which is a STREAM socket. hints.ai_socktype = SOCK_STREAM; // Convert the port into a string. char portString[6]; # ifdef MSVC sprintf_s(portString, "%d", port); # else sprintf(portString, "%d", port); # endif // Get the address info using the hints. addrinfo* result; if (getaddrinfo(ip.ToString().GetCString(), portString, &hints, &result) != 0) { throw NetworkException(NetworkExceptionCode::FAILED_CONNECT, NetworkExceptionReason::NO_NETWORK_INTERFACE); } // Create the socket. Because our hints are so strict, we don't have to worry about looping // through the linked list. We should be able to trust that the first result is what we want. sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (sock == INVALID_SOCKET) { freeaddrinfo(result); throw NetworkException(NetworkExceptionCode::FAILED_CONNECT, NetworkExceptionReason::FAILED_CREATE_SOCKET); } // Make the connection. if (::connect(sock, result->ai_addr, result->ai_addrlen) == SOCKET_ERROR) { freeaddrinfo(result); Close(); throw NetworkException(NetworkExceptionCode::FAILED_CONNECT, NetworkExceptionReason::FAILED_CONNECT_CALL); } // Make a non-blocking socket. if (!MakeNonBlocking()) { freeaddrinfo(result); Close(); throw NetworkException(NetworkExceptionCode::FAILED_CONNECT, NetworkExceptionReason::FAILED_NONBLOCKING); } // Turn off the Nagle Algorithm to increase speed. if (!MakeNoDelay()) { freeaddrinfo(result); Close(); throw NetworkException(NetworkExceptionCode::FAILED_CONNECT, NetworkExceptionReason::FAILED_NO_DELAY); } // Free up the address info linked list. freeaddrinfo(result); }
/** @brief Starts listening for clients on a specified port. * @param port The port number. * @param ipv4 Whether to use the local ipv4 address or not. Will use an ipv6 address otherwise. * @param backlog How many clients can wait to be accepted. Defaults to 10. */ void Jatta::Network::SocketTCP::Listen(unsigned short port, bool ipv4, int backlog) { // Convert the port into a string. char portString[6]; # ifdef MSVC sprintf_s(portString, "%d", port); # else sprintf(portString, "%d", port); # endif // Create a hints variable used to determine the connection configuration. struct addrinfo hints; memset(&hints, 0, sizeof(addrinfo)); // Check if IPv4 or IPv6. if (ipv4) { // Use IPv4. hints.ai_family = AF_INET; } else { // Use IPv6. hints.ai_family = AF_INET6; } // We're setting up a TCP/IP connection, which is a STREAM socket. hints.ai_socktype = SOCK_STREAM; // Pick the address for us (we'll use a local address) hints.ai_flags = AI_PASSIVE; // Get the address info using the hints. addrinfo* result; if (getaddrinfo(NULL, portString, &hints, &result) != 0) { throw NetworkException(NetworkExceptionCode::FAILED_LISTEN, NetworkExceptionReason::NO_NETWORK_INTERFACE); } // Create the socket. sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (sock == INVALID_SOCKET) { freeaddrinfo(result); throw NetworkException(NetworkExceptionCode::FAILED_LISTEN, NetworkExceptionReason::FAILED_CREATE_SOCKET); } // Bind the socket to the port. if (bind(sock, result->ai_addr, result->ai_addrlen) == SOCKET_ERROR) { freeaddrinfo(result); Close(); throw NetworkException(NetworkExceptionCode::FAILED_LISTEN, NetworkExceptionReason::FAILED_BIND_PORT); } // Start listening like the champ that we are. if (::listen(sock, backlog) == SOCKET_ERROR) { freeaddrinfo(result); Close(); throw NetworkException(NetworkExceptionCode::FAILED_LISTEN, NetworkExceptionReason::FAILED_LISTEN_CALL); } // Make a non-blocking socket. if (!MakeNonBlocking()) { freeaddrinfo(result); Close(); throw NetworkException(NetworkExceptionCode::FAILED_LISTEN, NetworkExceptionReason::FAILED_NONBLOCKING); } // Turn off the Nagle Algorithm to increase speed. if (!MakeNoDelay()) { freeaddrinfo(result); Close(); throw NetworkException(NetworkExceptionCode::FAILED_LISTEN, NetworkExceptionReason::FAILED_NO_DELAY); } // Free up the address info linked list. freeaddrinfo(result); }
void tconn::AcceptTask() { struct sockaddr_in clientaddr; socklen_t Len=sizeof(clientaddr); memset(&clientaddr,0,sizeof(clientaddr)); while(true) { int sock=accept(sockfd,(struct sockaddr*)&clientaddr,&Len); if(sock<0) { if(errno==EAGAIN) break; WARN("accept fail|%d|%s",errno,strerror(errno)); break; } if(!MakeNonBlocking(sock)) return; int iNodely=1; if(-1==setsockopt(sock,SOL_TCP,TCP_NODELAY,&iNodely,sizeof(iNodely))) { ERROR("setsockopt failed|%d%s",errno,strerror(errno)); return; } int cbuffsize=4*32768; DEBUG("trace"); if(setsockopt(sock,SOL_SOCKET,SO_SNDBUF,(void*)&cbuffsize,sizeof(cbuffsize))==-1) { WARN("set sendbuff size fail|%d|%s",errno,strerror(errno)); return; } if(setsockopt(sock,SOL_TCP,SO_RCVBUF,(void*)&cbuffsize,sizeof(cbuffsize))==-1) { WARN("set recvbuff size failed|%d|%s",errno,strerror(errno)); return; } unsigned int cpos=++curpos; INFO("new client connect,pos:%d",cpos); TaskPtr task; task.reset(new Task(cpos,sock,epollfd)); struct epoll_event event; event.data.u32=cpos; event.events=(EPOLLIN|EPOLLRDHUP|EPOLLERR|EPOLLRDHUP|EPOLLET); if(epoll_ctl(epollfd,EPOLL_CTL_ADD,sock,&event)!=0) { ERROR("epoll add failed,%d|%s",errno,strerror(errno)); return ; } INFO("new client socket add epoll success"); if(objtaskmap.insert(std::make_pair(cpos,task)).second==false) { ERROR("add task map failed,pos:%d",cpos); task->Terminate(); return; } INFO("add task map success,pos:%d",cpos); } INFO("add map success"); }