Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;

}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
/** @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);
}
Ejemplo n.º 5
0
/** @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);
}
Ejemplo n.º 6
0
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");
}