コード例 #1
0
static void
send_data(void)
{
  char buf[MAX_PAYLOAD_LEN];

  if (init_buffer(COAP_DATA_BUFF_SIZE)) {
    int data_size = 0;
    coap_packet_t* request = (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t));
    init_packet(request);

    coap_set_method(request, COAP_POST);
    request->tid = xact_id++;
    request->type = MESSAGE_TYPE_NON;
    coap_set_header_uri(request, service_url);

    data_size = serialize_packet(request, buf);

//    PRINTF("Client sending request to:[");
//    PRINT6ADDR(&client_conn->ripaddr);
//    PRINTF("]:%u/%s\n", (uint16_t)REMOTE_PORT, service_urls[service_id]);
    uip_udp_packet_send(client_conn, buf, data_size);

    delete_buffer();
  }
}
コード例 #2
0
static
void send_data()
{
  int data_size = 0;
  static unsigned temperature;

  temperature = 21;
  clear_buffer(outputBuffer);
  clear_buffer(payload_buf);
  generate_payload(payload_buf,temperature);

  if(init_buffer(COAP_DATA_BUFF_SIZE)){
    coap_packet_t* request =\
    (coap_packet_t*)allocate_buffer(sizeof(coap_packet_t));
    init_packet(request);
    coap_set_method(request, COAP_POST);
    request->tid = xact_id++;
    request->type = MESSAGE_TYPE_CON;
    coap_set_header_uri(request,service_uri);
    coap_set_option(request, Option_Type_Uri_Host,
      sizeof(char)*strlen(server_ip), (uint8_t*)server_ip);
    coap_set_option(request, Option_Type_Proxy_Uri,
    sizeof(char)*strlen(proxy_uri), (uint8_t*)proxy_uri);
    coap_set_payload(request,(uint8_t*)payload_buf,
    sizeof(char)*strlen(payload_buf));
    data_size = serialize_packet(request, (uint8_t*)outputBuffer);

    PRINTF("Now sending request to base station [");
    PRINTF(&client_conn->ripaddr);
    PRINTF("]:%u/%s\n",REMOTE_PORT,service_uri);
    uip_udp_packet_send(client_conn, outputBuffer, data_size);
    delete_buffer();
  }
}
コード例 #3
0
ファイル: tunneld.cpp プロジェクト: kitech/toxsh
static int toxenet_socket_send (ENetSocket socket, const ENetAddress * address,
                                const ENetBuffer * buffers, size_t bufferCount,
                                ENetPeer *enpeer, void *user_data)
{
    Tunneld *tund = (Tunneld*)user_data;
    QToxKit *toxkit = tund->m_toxkit;    
    // ToxTunChannel *chan = tund->m_enpeer_chans[enpeer];
    // ToxTunChannel *chan = tund->m_conid_chans[(uint32_t)(enpeer->data)];
    // ToxTunChannel *chan = (ToxTunChannel*)enpeer->toxchan;
    ToxTunChannel *chan = tund->peerLastChan(enpeer);
    // qDebug()<<bufferCount<<toxkit<<enpeer<<chan;

    if (enpeer == NULL) {}
    if (chan == NULL) {
        qDebug()<<"maybe connect/ping/disconnect."<<enpeer
                <<"i/o:"<<enpeer->incomingPeerID<<enpeer->outgoingPeerID;
    }
    
    size_t sentLength = 0;
    // QString friendId = "451843FCB684FC779B302C08EA33DDB447B61402B075C8AF3E84BEE5FB41C738928615BCDCE4";
    // QString friendId = QString(address->toxid);
    QString friendId = toxkit->friendGetPublicKey(address->vaddr);
    int idsrc = 0;
    if (chan != NULL) { // connected state
        // qDebug()<<chan;
        // qDebug()<<chan->m_peer_pubkey;
        friendId = chan->m_peer_pubkey;
        idsrc = 1;
    } else { // not connected state
        // friendId = QString(address->toxid);
        friendId = toxkit->friendGetPublicKey(address->vaddr);
        idsrc = 2;
    }
    // qDebug()<<"sending to:"<<friendId<<QString(enpeer->toxid)<<idsrc;
    Q_ASSERT(friendId.length() > 0);
    if (friendId.length() == 0) {
        // send to who???
        // return 0;
    }
    
    QByteArray data = serialize_packet(address, buffers, bufferCount);
    bool bret = tund->m_toxkit->friendSendLossyPacket(friendId, data);
    if (!bret) { return 0; }
    
    // tund->m_toxkit->friendSendMessage(friendId, data);
    for (int i = 0; i < bufferCount; i ++) {
        sentLength += buffers[i].dataLength;  
    }

    // for (int i = 0; i < bufferCount; i++) {
    //     QByteArray data = serialize_packet(address, &buffers[i]);
    //     toxkit->friendSendMessage(QString(), data);
    // }

    return sentLength;
    return 0;
}
コード例 #4
0
ファイル: tunnelc.cpp プロジェクト: kitech/toxsh
static int toxenet_socket_send (ENetSocket socket, const ENetAddress * address,
                                const ENetBuffer * buffers, size_t bufferCount,
                                ENetPeer *enpeer, void *user_data)
{
    Tunnelc *tunc = (Tunnelc*)user_data;    
    QToxKit *toxkit = tunc->m_toxkit;

    // ToxTunChannel *chan = tunc->m_enpeer_chans[enpeer];
    // ToxTunChannel *chan = (ToxTunChannel*)enpeer->toxchan;
    ToxTunChannel *chan = tunc->peerLastChan(enpeer);
    // qDebug()<<bufferCount<<toxkit<<enpeer<<chan;

    if (enpeer == NULL) {}
    if (chan == NULL) {
        qDebug()<<"maybe connect/ping/disconnect."<<enpeer
                <<"i/o:"<<enpeer->incomingPeerID<<enpeer->outgoingPeerID;
    }

    size_t sentLength = 0;
    // QString friendId = QString(address->toxid);
    QString friendId = toxkit->friendGetPublicKey(address->vaddr);
    int idsrc = 0;
    if (chan != NULL) { // connected state
        friendId = chan->m_peer_pubkey;
        idsrc = 1;
    } else { // not connected state
        // friendId = QString(address->toxid);
        friendId = toxkit->friendGetPublicKey(address->vaddr);
        idsrc = 2;
    }
    // qDebug()<<"sending to:"<<friendId<<QString(enpeer->toxid)<<idsrc;
    if (friendId.length() == 0) {
        // why?????
    }
    
    QByteArray data = serialize_packet(address, buffers, bufferCount);
    bool bret = toxkit->friendSendLossyPacket(friendId, data);
    if (!bret) { return 0; }
    
    // toxkit->friendSendMessage(friendId, data);
    for (int i = 0; i < bufferCount; i ++) {
        sentLength += buffers[i].dataLength;
    }

    // for (int i = 0; i < bufferCount; i++) {
    //     QByteArray data = serialize_packet(address, &buffers[i]);
    //     toxkit->friendSendMessage(friendId, data);
    //     sentLength += buffers[i].dataLength;
    // }

    return sentLength;
    return 0;
}
コード例 #5
0
void convert(const stdr_msgs::RawScans & in, velodyne_msgs::VelodyneScan & out)
{
  // if this fails, then I will have to implement something more complex
  ROS_ASSERT( in.scans.size() % velodyne_rawdata::BLOCKS_PER_PACKET == 0 );

  out.header = in.header;
  out.packets.resize(in.scans.size()/velodyne_rawdata::BLOCKS_PER_PACKET);
  for( unsigned i=0; i<out.packets.size(); ++i ) {
    const unsigned I = i*velodyne_rawdata::BLOCKS_PER_PACKET;
    serialize_packet( &(out.packets[i].data[0]), &(in.scans[I]) );
    out.packets[i].stamp = in.scans[I].stamp;
  }
}
コード例 #6
0
void send_packet(gg_socket *s, pkt_t *packet) {
  uint8_t *raw_packet;
  int bytes_sent = 0;
  int ret = 0;

  raw_packet = serialize_packet(packet);

  while(ret+bytes_sent < packet->pkt_len) {
    bytes_sent += ret;
    ret = write(s->s, raw_packet+bytes_sent, packet->pkt_len-bytes_sent);
  }

  free(raw_packet);
}
コード例 #7
0
/*
*
*	Broadcasts distance vector to all neighbors
*
*/
void send_update_pkt(){
	struct sockaddr_in dest_ip_struct; 
	char ip_presentation[15];
	int i;


	for(i=0;i<num_of_servers;i++) {
		inet_ntop(AF_INET,&servers[i].server_ip,ip_presentation,sizeof(ip_presentation));


		if(servers[i].is_neighbor==1 && servers[i].is_alive==1){
			//printf("Sending update packet to ID: %d IP: %s on %d\n",servers[i].server_id,ip_presentation,servers[i].server_port);

			memset(&dest_ip_struct, 0, sizeof(struct sockaddr_in));

			dest_ip_struct.sin_family = AF_INET;

			//struct in_addr ip_struct;
			//inet_aton(servers[i].server_ip, &ip_struct); 

			dest_ip_struct.sin_addr.s_addr= servers[i].server_ip;
			dest_ip_struct.sin_port = htons(servers[i].server_port); 
			int MAX_PKT_SIZE=sizeof(struct routing_update_pkt)+(sizeof(struct distance_vector)*num_of_servers);

			char send_buf[1000]; 
			struct routing_update_pkt *packet_to_send;
			packet_to_send=(struct routing_update_pkt *)malloc(sizeof(struct routing_update_pkt) + sizeof(struct distance_vector) * num_of_servers);
			packet_to_send->updates=malloc(sizeof(struct distance_vector) * num_of_servers);

			prepare_update_pkt(packet_to_send); // fills packet_to_send with routing information
			serialize_packet(packet_to_send,&send_buf); 

			if(sendto(my_socket, &send_buf, sizeof(send_buf), 0, &dest_ip_struct, sizeof(dest_ip_struct))<0){
				perror("send");


			}
			else{
				printf("Sent update packet to ID: %d IP: %s on %d\n",servers[i].server_id,ip_presentation,servers[i].server_port); //segfault
						

			}
				

		}
	}
}
コード例 #8
0
/*
 * Function that sends cumulative ACK.
 */
void send_ack()
{
    int len;
    udp_pack ack_packet;
    initialize_packet(&ack_packet, port, sequence_num, 1);
    ack_packet.ack_num = ordered_count + 1;
    strcpy(ack_packet.data, NODATA);

    char *ackpack = (char *)malloc(MTU*sizeof(char));
    bzero(ackpack, MTU);
    strcpy(ackpack, serialize_packet(ack_packet));

    len = sendto(client_sfd, ackpack, strlen(ackpack), 0, (struct sockaddr *) &server_addr, clen);
    if (n < 0)
    {
      printf("\nError while sending ACK at current count = %d\n", ordered_count);
      report_error("ERROR: Sending ACK");
    }
    sequence_num++;
    printf("\nACK: %d Sent\n", ack_packet.ack_num);
}
コード例 #9
0
/*
 * Function to establish handshake.
 */
int establish_handshake(char *req_file)
{
    int success = 0, n;

    udp_pack syn, synack, ack;

    fd_set fds;                // fd set declare
    struct timeval time_out;   // Struct for Timeout value

    initialize_packet(&syn, 2222, sequence_num, 0);

    char *synreq = (char *)malloc(MTU*sizeof(char));
    bzero(synreq, MTU);
    strcpy(synreq, serialize_packet(syn));

    // SYN
    //printf("\nSYN to send: %s", synreq);
    n = sendto(client_sfd, synreq, strlen(synreq), 0, (struct sockaddr *) &server_addr, clen);
    if (n < 0)
    {
      report_error("HANDSHAKE ERR: writing to socket for SYN");
    }
    sequence_num++;
    printf("\nHANDSHAKE SYN Sent\n");
    //gettimeofday(&start_timev,NULL);

    printf("\a");
    char *buffer = (char *)malloc(MTU*sizeof(char));
    bzero(buffer, MTU);

    // SYN-ACK
    FD_ZERO(&fds);             // Clear the fd set
    FD_SET(client_sfd, &fds);           // Set the client fd for select

    time_out.tv_sec = 0;
    time_out.tv_usec = timeout;

    // Waiting until timeout for SYNACK
    if ( select(32, &fds, NULL, NULL, &time_out) == 0 )
    {
        printf("SYNACK receiving timed out...\n");
    }
    else
    {
        bzero(buffer, MTU);
        n = recvfrom(client_sfd, buffer, MTU, 0, (struct sockaddr *) &server_addr, &clen);
        if (n < 0)
        {
          report_error("HANDSHAKE ERR: reading from socket for SYNACK");
        }
        //printf("\nSYNACK response: %s", buffer);

        synack = deserialize_data(buffer);

        if(synack.is_ack != 1)
        {
            report_error("HANDSHAKE ERR: SYNACK not received from server during handshake");
        }
        printf("\nHANDSHAKE SYNACK received\n");

        ack = synack;
        ack.seq_num = sequence_num;
        ack.ack_num = ack.seq_num + 1;
        ack.is_ack = 1;
        memset(ack.data, 0, DATALEN);
        strcpy(ack.data, req_file);

        char *ackpack = (char *)malloc(MTU*sizeof(char));
        bzero(ackpack, MTU);
        strcpy(ackpack, serialize_packet(ack));

        //printf("Filename sent : %s", ackpack);

        // ACK
        //printf("\nACK to send: %s", ackpack);
        n = sendto(client_sfd, ackpack, strlen(ackpack), 0, (struct sockaddr *) &server_addr, clen);
        if (n < 0)
        {
          report_error("HANDSHAKE ERR: writing to socket Handshake ACK");
        }
        printf("\nHANDSHAKE ACK Sent\n");
        sequence_num++;

        success = 1;
        printf("\n-------- Handshake Successful --------\n");
    }
    return success;
}
コード例 #10
0
ファイル: sender.c プロジェクト: sridatta/ee122-proj3
int main(int argc, char *argv[]) {

    if(argc != 7) {
        printf("usage: host port R stream_id window_size filename\n");
        exit(0);
    }

    char *endptr;
    long R = strtol(argv[3], &endptr, 10);
    char *stream_id = argv[4];
    int window_size = strtol(argv[5], NULL, 10);

    if(endptr != (argv[3] + strlen(argv[3]))) {
        fprintf(stderr, "R must be an integer (milliseconds).\n");
        exit(1);
    }


    struct addrinfo* p;
    int send_sock = send_port(argv[1], argv[2], &p);
    int recv_sock = recv_port(NULL, argv[2]);// TODO fix


    printf("Stream id = %s\n", stream_id);
    ee122_packet pkt;
    pkt.R = R;
    pkt.stream = *stream_id;
    printf("pkt.stream = %c\n", pkt.stream);
    pkt.avg_len = 0;
    pkt.window_size = window_size;

    int read_count;
    char fbuff[sizeof(pkt.payload)];
    memset(fbuff,0,sizeof(fbuff));
    FILE *fd = fopen(argv[6], "rb");
    if(NULL == fd) {
        fprintf(stderr, "fopen() error\n");
        return 1;
    }

    ee122_packet rcv_pkt;

    struct timespec sleep_spec;
    sleep_spec.tv_sec = 0;

    struct timeval curr_time, start_time, last_generated, diff_time;
    gettimeofday(&start_time, NULL);
    gettimeofday(&last_generated, NULL);

    int seq_no = 0;
    int available_window = window_size;

    struct timeval timeouts[window_size+1];
    ee122_packet packets[window_size+1];

    int i;
    struct timeval zero_timeout;
    zero_timeout.tv_usec = 0;
    zero_timeout.tv_sec = 0;

    for(i = 0; i < window_size+1; i++) {
        memcpy(&timeouts[i], &zero_timeout, sizeof(zero_timeout));
    }

    bytequeue q;
    bytequeue_init(&q, sizeof(ee122_packet), window_size);

    float rtt = 400*1000;
    char buff[sizeof(ee122_packet)];

    float next_wait = rand_poisson(R);
    printf("next wait: %f\n", next_wait);

    int bytes_read;
    struct sockaddr src_addr;
    int src_len = sizeof(src_addr);
    int last_received = -1;
    unsigned total_attempts = 0;
    unsigned seconds = 0;
    unsigned errors = 0;

    while (1) {
        gettimeofday(&curr_time, NULL);

        timeval_subtract(&diff_time, &curr_time, &start_time);

        if (diff_time.tv_sec * 1000000 + diff_time.tv_usec > seconds * 1000000) {
            printf("%f,%d\n", rtt, seconds);
            seconds++;
        }
        // Stop sending after 60 seconds
        if(diff_time.tv_sec * 1000000 + diff_time.tv_usec > 60*1000000) {
            break;
        }

        // Check timeouts. If timeout reached, retransmit that packet and all following.
        int retransmitting = -1;
        int i;
        for(i=0; i < window_size+1; i++) {
            struct timeval timeout = timeouts[i];
            if(timeout.tv_sec == 0 && timeout.tv_usec == 0) continue;

            timeval_subtract(&diff_time, &curr_time, &timeouts[i]);
            if(diff_time.tv_sec * 1000000 + diff_time.tv_usec > rtt) {
                retransmitting = i;
                break;
            }
        }

        if(retransmitting != -1) {
            i = retransmitting;
            do {
                struct timeval timeout = timeouts[i];
                if(timeout.tv_sec == 0 && timeout.tv_usec == 0) {
                    i = (i + 1) % (window_size+1);
                    continue;
                }
                //printf("Retransmitting seq_no == %d, stream == %c, rtt == %f\n", packets[i].seq_number, packets[i].stream, rtt);
                // Reset the timeout for this packet and send.
                gettimeofday(&(timeouts[i]), NULL);
                serialize_packet(buff, packets[i]);
                sendto(send_sock, buff, sizeof(packets[i]), 0, p->ai_addr, p->ai_addrlen);
                i = (i + 1) % (window_size+1);
                total_attempts++;
                errors++;
            } while (i != retransmitting);
        }

        // Check if new packet should be generated by now
        timeval_subtract(&diff_time, &curr_time, &last_generated);
        if(diff_time.tv_sec * 1000000 + diff_time.tv_usec > next_wait * 1000) {
            // Enqueue the packet.
            bytequeue_push(&q, &pkt);
            next_wait = rand_poisson(R);
        }

        // Read from socket. Increase available window for each ack received
        int bytes_read = recvfrom(recv_sock, buff, sizeof(ee122_packet), 0, &src_addr, &src_len);
        if(bytes_read > 0) {
            rcv_pkt = deserialize_packet(buff);
            if(rcv_pkt.stream == 'Z' && rcv_pkt.seq_number == (last_received + 1) % (window_size+1)) {
                struct timeval timeout_start = rcv_pkt.timestamp;

                // Learn RTT
                timeval_subtract(&diff_time, &curr_time, &timeout_start);
                //printf("RTT difftime, tv_sec == %d, tv_usec == %d\n", diff_time.tv_sec, diff_time.tv_usec);
                rtt = (0.6 * (diff_time.tv_sec * 1000000 + diff_time.tv_usec)) + 0.4*rtt;

                // Reset this timeout
                timeouts[rcv_pkt.seq_number].tv_usec = 0;
                timeouts[rcv_pkt.seq_number].tv_sec = 0;

                available_window += 1;
                last_received = rcv_pkt.seq_number % (window_size+1);
            }
            else {
                //printf("Received ACK with seq = %d, expecting = %d\n", rcv_pkt.seq_number, (last_received + 1) % window_size);
            }
        }

        // Check available window. If available, dequeue and send a packet.
        if(available_window > 0 && q.filled != 0) {
            bytequeue_pop(&q, &pkt);

            total_attempts++;

            pkt.seq_number = (seq_no) % (window_size+1);
            pkt.timestamp = curr_time;
            pkt.total_attempts = total_attempts;
            pkt.timeout = rtt;
            read_count = fread(pkt.payload, sizeof(char), sizeof(pkt.payload), fd);

            //printf("Sending. Seq_no == %d, stream == %c\n", pkt.seq_number, pkt.stream);
            serialize_packet(buff, pkt);

            //Store the packet into the packets buffer for possible transmission
            memcpy(&packets[pkt.seq_number], &pkt, sizeof(pkt));

            sendto(send_sock, buff, sizeof(pkt), 0, p->ai_addr, p->ai_addrlen);
            pkt = deserialize_packet(buff);
            available_window -= 1;

            if (feof(fd)) break;
            if(ferror(fd)) {
                fprintf(stderr, "error: %s\n", strerror(errno));
                exit(3);
            }

            // Set this timeout
            gettimeofday(&timeouts[pkt.seq_number], NULL);

            seq_no++;
        }

    }

    printf("Total errors: %d. Total total:%d\n", errors, total_attempts);

    close(send_sock);
    close(recv_sock);
    exit(0);
}
コード例 #11
0
ファイル: receiver_aimd.c プロジェクト: sridatta/ee122-proj3
int main(int argc, char *argv[]){

  if(argc != 5){
    printf("usage: port sender_hostname ack_port filename\n");
    exit(0);
  }

  srand(time(0)); // init random

  int status;
  int sockfd;

  struct addrinfo hints;
  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_INET;
  hints.ai_socktype = SOCK_DGRAM;
  hints.ai_flags = AI_PASSIVE;

  struct addrinfo *res, *p;

  if ((status = getaddrinfo(NULL, argv[1], &hints, &res)) != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    exit(1);
  }

  for(p = res; p != NULL; p = p->ai_next) {
    if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
        perror("listener: socket");
        continue;
    }

    if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
      close(sockfd);
      perror("listener: bind");
      continue;
    }

    break;
  }

  if (p == NULL) {
    fprintf(stderr, "listener: failed to bind socket\n");
    return 2;
  }

	struct addrinfo* send_p;
  int outsock = send_port(argv[2], argv[3], &send_p);

  struct timeval timeout;

  timeout.tv_sec = 4;
  timeout.tv_usec = 0;
  setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,(struct timeval *)&timeout, sizeof(struct timeval));

  struct sockaddr src_addr;
  int src_len = sizeof src_addr;
  ee122_packet pkt;

  int write_count;
  char fbuff[sizeof(pkt.payload)];
  memset(fbuff,0,sizeof(fbuff));
  FILE *fd = fopen(argv[4], "wb");
  if(NULL == fd) {
    fprintf(stderr, "fopen() error\n");
    return 1;
  }

  int num_rcv = 0;
  int bytes_read = 0;
  unsigned long attempted = 0;
  float avg_len ;

  unsigned char buff[sizeof(ee122_packet)];
  long R;

  int delay;
  struct timespec sleep_spec;
  sleep_spec.tv_sec = 0;

  struct timeval last_time, curr_time, diff_time, last_print;
  gettimeofday(&last_print, NULL);

  double sum = 0.0;

  int seq_expected = 0;
  int gotten = 0;

  float efficiency = 0;

  while(bytes_read = recvfrom(sockfd, buff, sizeof(ee122_packet), 0, &src_addr, &src_len)){
    if(bytes_read == -1){
      if(num_rcv > 0){
        break;
      }
    } else {
      if(bytes_read == 0){
        break;
      }

      pkt = deserialize_packet(buff);

      //printf("Received packet with seq no: %d\n", ntohl(*((uint32_t*) buff)));
      if(num_rcv == 0) {
        R = pkt.R;
      } else {
      }

      if (flip_state) {
        delay = rand() % 15;
      }
      else {
        delay = rand() % 5;
      }

      sleep_spec.tv_nsec = delay * 1000000;
      nanosleep(&sleep_spec, &sleep_spec);
      if(pkt.seq_number == seq_expected){
        write_count = fwrite(pkt.payload, sizeof(char), sizeof(pkt.payload), fd);
        if (ferror(fd)) {
          fprintf(stderr, "error: %s\n", strerror(errno));
          exit(3);
        }
        seq_expected = (seq_expected + 1) % (MAX_WINDOW + 1);

        // Do the calcs
        num_rcv++;
        attempted = pkt.total_attempts;
        avg_len = pkt.avg_len;
        gettimeofday(&curr_time, NULL);
        last_time = pkt.timestamp;
        timeval_subtract(&diff_time, &curr_time, &last_time);
        sum += ((double)(diff_time.tv_sec)) + (diff_time.tv_usec / 1000000.0);

        timeval_subtract(&diff_time, &curr_time, &last_print);
        if (diff_time.tv_sec * 1000000 + diff_time.tv_usec > 1000000) {
          printf("%f\n", ((float) num_rcv)/attempted);
          gettimeofday(&last_print, NULL);
        }
      }

      gotten = pkt.total_attempts;

      // Send ACK
      ee122_packet ack;
      ack = pkt;
      ack.stream = 'Z';

      unsigned char buff[sizeof(ack)];
      serialize_packet(buff, ack);
			sendto(outsock, buff, sizeof(ack), 0, send_p->ai_addr, send_p->ai_addrlen);
    }
  }

  printf("%d,%f,%lf\n", pkt.R, ((float) num_rcv)/attempted, avg_len);

  freeaddrinfo(res);
  close(sockfd);
  exit(0);
}