/* * 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; }
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; }