Exemplo n.º 1
0
/*
 * Read data from the network.
 * Write data to ring buffer.
 */
void receive_packets(int fifo)
{
    
	socket_t sock = setup_network_listener();
	int numbytes, bytesinfifo;
	struct sockaddr_storage their_addr;
	char buf[PACKET_SIZE_BYTES];
	size_t addr_len;
	//char s[INET6_ADDRSTRLEN];
    int numpackets=0;
    long long totalbytes=0;
    long long currentpacket=0;
    long long newpacket=0;
    long long errors=0;
    int i;
    
    
	fprintf(stderr, "Entering network thread loop.\n");
    
	/*
	 * loop forever:
	 *   read data from network
	 */
    while(run_net_thread)
    {
        //printf("listener: waiting to recvfrom...\n");
        
        if ((numbytes = recvfrom(sock, buf, PACKET_SIZE_BYTES , 0,
                                 (struct sockaddr *)&their_addr, (socklen_t *) &addr_len)) == -1) {
            if(errno==EINTR && run_net_thread==0)
            {
                perror("Interrupt received and handled");
            }
            else
            {
                perror("Unable to receive packet");
                exit(1);
            }
        }
        else
        {
            /*
             debug_fprintf(stderr, "[net thread] Received %d bytes.\n", numbytes);
             debug_fprintf(stderr, "listener: got packet from %s\n",
             inet_ntop(their_addr.ss_family,
             get_in_addr((struct sockaddr *)&their_addr),
             s, sizeof s));
             debug_fprintf(stderr,"listener: packet is %d bytes long\n", numbytes);
             debug_fprintf(stderr,"listener: packet contains \"%s\"\n", buf);
             */
            
            //send packets over the fifo
            //bytesinfifo = write(fifo, buf, numbytes);
            //debug_fprintf(stderr, "wrote %d bytes to fifo\n", bytesinfifo);
            numpackets++;
            totalbytes+=numbytes;
            newpacket = ntohll(((uint64_t *) buf)[PACKET_SIZE_BYTES/8-1]);
            if(currentpacket+1 != newpacket)
            {
                errors++;
            }
            currentpacket = newpacket;
            
        }
    }
    for(i=0;i<PACKET_SIZE;i++)
    {
        fprintf(stderr, "%lld ", ntohll(((uint64_t *) buf)[i]));
    }
    
	fprintf(stderr, "Exiting network thread loop.\n");
    fprintf(stderr, "Received %d packets, %lld bytes, %lld errors\n", numpackets, totalbytes, errors);
    
	close(sock);
    
	return;
}
Exemplo n.º 2
0
void *net_thread_function(void *arg) {
    /* This thread puts data into a ring buffer from a socket*/
    BufferSocket *bs = (BufferSocket *)arg;
    RING_ITEM *this_slot;

    socket_t sock = setup_network_listener((short) bs->port);
    SA_in addr; // packet source's address
    socklen_t addr_len = sizeof(addr);
    ssize_t num_bytes = 0;
    fd_set readset;
    struct timeval tv;
    struct timespec ts;
    long timeouts = 0;

    // If sock open fails, end all threads
    if (sock == -1) {
        fprintf(stderr, "Unable to open socket.\n");
        bs->run_threads = 0;
        return NULL;
    }

    while (bs->run_threads) {
        this_slot = bs->buf->write_ptr;
        if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
            fprintf(stderr, "Net: clock_gettime returned nonzero.\n");
            bs->run_threads = 0;
            continue;
        }
        ts.tv_nsec += TIMEOUT_USEC*1000;
        // Wait for next buffer slot to open up
        if (sem_timedwait(&this_slot->write_mutex, &ts) == -1) continue;
        
        // Poll to see if socket has data
        while (bs->run_threads) {
            FD_ZERO(&readset);
            FD_SET(sock, &readset);
            tv.tv_sec = 0; tv.tv_usec = TIMEOUT_USEC;
            num_bytes = select(sock + 1, &readset, NULL, NULL, &tv);
            // Read data from socket into ring buffer
            if (num_bytes > 0) {
                num_bytes = recvfrom(sock, this_slot->data, 
                    bs->buf->buffer_size / bs->buf->list_length, 
                    0, (SA *)&addr, &addr_len);
                timeouts = 0;
                break;
            } else if (num_bytes < 0) {
                if (errno == EINTR) continue;
                fprintf(stderr, "Unable to receive packets.\n");
                bs->run_threads = 0;
            } else  { // num_bytes == 0
                timeouts += TIMEOUT_USEC;
                if(timeouts >= 60*1000*1000) {
                    fprintf(stdout, "No packets received for 60 seconds on port %d.\n", bs->port);
                    syslog(LOG_WARNING, "no packets received for 60 seconds on port %d\n", bs->port);
                    // Send self the INT signal (simulate ctrl-c)
                    raise(SIGINT);
                    timeouts = 0;
                }
            }
            //printf("run_threads=%d num_bytes=%d errno=%d(%d)\n", bs->run_threads, num_bytes, errno, EINTR);
        }

        if (num_bytes > 0) {
            //printf("Wrote in a packet: size=%d slot=%d\n", num_bytes, this_slot - bs->buf->list_ptr);
            this_slot->size = num_bytes;
            // Mark this slot ready for readout
            sem_post(&this_slot->read_mutex);
            bs->buf->write_ptr = this_slot->next;
        }
    }
    close(sock);
    return NULL;
}