Exemple #1
0
void on_recv(int fd, void *arg)
{
    char buf[128] = {0};
    int sock_type = get_socket_type(fd);
    int proto_type = get_socket_protocol(fd);

    switch (sock_type) {
        case SOCK_STREAM:
            if (proto_type == IPPROTO_TCP)
                socket_recv(fd, buf, sizeof(buf));
            else if (proto_type == IPPROTO_SCTP) ;
            else return; 
            break;
        case SOCK_DGRAM:
            socket_addr_recvfrom(fd, buf, sizeof(buf), 
                    (void *)&((struct socket_impl *)arg)->addr.in_addr);
            break;
        default:
            return;
            break;
    }

    printf("recv from %s: %s\n", 
            inet_ntoa(((struct socket_impl *)arg)->addr.in_addr.sin_addr), 
            buf);
}
int reopen_socket_with_other_family(int s, int family)
{
	int type, protocol, result, saved_fd;

	result = 0;

	// duplicate the file descriptor
	saved_fd = dup(s);

	// record the type, protocol and fd of the existing socket
	type = get_socket_type(s);
	protocol = get_socket_protocol(s);
	
	// close the socket - this way the fd integer should be available for our new socket
	// and the calling program will not notice that the socket is not the same
	original_close(s);

	// create an IPv6 socket on the same file descriptor s
	if (create_socket_on_specified_free_fd(s, family, type, protocol) == -1)
	{	// failed ! recreate file descriptor previously closed
		dup2(saved_fd, s);
		result = -1;
	}
	else
	{
		report_socket_options(saved_fd, s);
	}

	// saved_fd is not useful anymore
	original_close(saved_fd);

	return result;
}
Exemple #3
0
/**
 * @brief tcp_server thread runine
 *
 * @param sock [in] struct sock
 *
 * @return 
 */
static  void* tcp_server_backup_service(void *sock)
{
    /* define */
    struct socket_impl *sck = (struct socket_impl *)sock;
    struct event_loop *evl = (event_loop_t *)&sck->evl;
    struct timeval tv = {0};
    fd_set set;
    fd_set allset;
    int can_recv_bytes = 0;
    int nready = 0;
    int serfd = sck->fd;
    int maxfd = sck->fd;
    int clifd = -1;
    int fd = -1;
    int maxi = -1;
    int i = 0;
    int addr_len = sizeof(struct sockaddr);

    /* avoid sock equal to NULL */
    if (sock == NULL) return NULL;

    /* client socket fd init */
    for (i = 0; i < MAX_CLIENT_NUM; i++)
        sck->cli_fd[i] = -1;

    /* empty fd sets */
    FD_ZERO(&allset);
    FD_SET(serfd, &allset);
    
    /* detect socket state looply */
    while (1)
    {
        /* set timer */
        tv.tv_sec = 0;
        tv.tv_usec = 10000;

        /* set fd sets */
        set = allset;
        
        /* time waiting */
        nready = select(maxfd + 1, &set, NULL, NULL, &tv);

        /* detect server socket state */
        if (FD_ISSET(serfd, &set))
        {
            /* accept socket */
            //clifd = socket_accept(serfd);
            clifd = accept(serfd, \
                    (struct sockaddr *)&sck->addr.in_addr, 
                    (socklen_t *)&addr_len);
            
            /* on_accept */
            if (clifd > 0)
                socket_event_process(clifd, evl->on_accept);

            for (i = 0; i < MAX_CLIENT_NUM; i++)
            {
                if (sck->cli_fd[i] < 0) 
                {
                    sck->cli_fd[i] = clifd;
                    break;
                }
            }

            if (i == MAX_CLIENT_NUM)
                printf("too many client!\n");
            
            /* add socket fd to the collection */
            FD_SET(clifd, &allset);
            
            /* set maxfd and maxi*/
            if (clifd > maxfd) maxfd = clifd;
            if (i > maxi) maxi = i;

            if (--nready <= 0) continue;
        }

        /* detect client socket state */
        for (i = 0; i <= maxi; i++)
        {
            if ((fd = sck->cli_fd[i]) < 0) continue;

            if (FD_ISSET(fd, &set))
            {
                /* on_recv */
                can_recv_bytes = get_can_read_bytes(fd);
                if (can_recv_bytes > 0 || get_socket_protocol(fd) == IPPROTO_SCTP)
                {
                    socket_event_process(fd, evl->on_recv);
                    sck->curr_cli_fd = fd;
                }
                
                /* on_close */
                if (can_recv_bytes <= 0)
                {
                    FD_CLR(fd, &allset);
                    socket_event_process(fd, evl->on_close);

                    if (fd > 0)close(fd);
                    sck->cli_fd[i] = -1;
                }

                if (--nready <= 0) break;
            }
        }
    }

    return NULL;
}