示例#1
0
STATE filename(char *fname, int32_t buf_size)
{
    uint8_t packet[MAX_LEN];
    uint8_t buf[MAX_LEN];
    uint8_t flag = 0;
    int32_t seq_num = 0;
    int32_t fname_len = strlen(fname) + 1;
    int32_t recv_check = 0;

    memcpy(buf, &buf_size, 4);
    memcpy(&buf[4], fname, fname_len);

    send_buf(buf, fname_len + 4, &server, FNAME, 0, packet);

    if (select_call(server.sk_num, 1, 0, NOT_NULL) == 1) {
        recv_check = recv_buf(packet, 1000, server.sk_num, &server, &flag, &seq_num);

        /* check for bit flip ... if so, send the file name again */
        if (recv_check == CRC_ERROR)
            return FILENAME;

        if (flag == FNAME_BAD)
        {
            printf("File %s already exists and is write-protected\n", fname);
            return DONE;
        }

        return FILE_OK;
    }
    return FILENAME;
}
示例#2
0
STATE wait_on_ack()
{
    static int32_t send_count = 0;
    uint32_t crc_check = 0;
    uint8_t buf[MAX_LEN];
    int32_t len = 1000;
    uint8_t flag = 0;
    int32_t seq_num = 0;

    send_count++;
    if (send_count > 5)
    {
        printf("Sent data 5 times, no ACK, client session terminated\n");
        return(DONE);
    }

    if (select_call(server.sk_num, 1, 0, NOT_NULL) != 1)
    {
        return (TIMEOUT_ON_ACK);
    }

    crc_check = recv_buf(buf, len, server.sk_num, &server, &flag, &seq_num);

    if (crc_check == CRC_ERROR)
        return WAIT_ON_ACK;

    if (flag != ACK)
    {
        printf("In wait_on_ack but its not an ACK flag (this should never happen) is: %d\n", flag);
        exit(-1);
    }
    /* ack is good so reset count and then go send some more data */
    send_count = 0;
    return SEND_DATA;
}
示例#3
0
文件: rcopy.c 项目: jtdreisb/networks
STATE recv_eof(Window *window, int output_fd)
{
	uint8_t flag = 0;
	int32_t data_len = 0;
	uint8_t data_buf[MAX_PACKET_LEN];
	uint32_t seq_num = nextOpenSequenceNumber(window);

	send_ack(seq_num);
	// Drain the packet queue
	while (select_call(server.socket_num, 1, 0, NOT_NULL) == 1) {
		data_len = recv_buf(data_buf, MAX_PACKET_LEN, server.socket_num, &server, &flag, &seq_num);
		return STATE_EOF;
	}

	printf("File Transfer Complete\n");
	return STATE_DONE;
}
示例#4
0
文件: server.c 项目: AsBeug/Shoool
/**
 * Receive the initial packet.
 * If no data is received, result = RES_NO_DATA and p_init_pkt is undefined;
 * Else if data is received but is corrupted, result = RES_DATA_CORRUPT;
 * Else if data is received but file cannot be opened, result = RES_FILE_ERR;
 * Else, data is received and check sum is verified, result = RES_SUCCESS, p_init_pkt contains init info
 *  and file
 **/
int recv_init(int sock_num, struct sockaddr_in * p_cli_addr, init_pkt_t ** p_p_init_pkt, FILE ** p_p_file) {
    int result = RES_NO_DATA;
    
    //debug_max("--------- receive init packet (wait %i secs) ---------\n", SRV_WAIT_SECS);
    if (select_call(sock_num, SRV_WAIT_SECS, 0)) {
        /* Get the packet */
        char * data_buff = malloc(MAX_INIT_PKT_SZ);
        recv_packet(sock_num, data_buff, MAX_INIT_PKT_SZ, p_cli_addr);
        //int bytes_trfd = recv_packet(sock_num, data_buff, MAX_INIT_PKT_SZ, p_cli_addr);
        //debug_max("recv_init(): bytes_trfd = %i\n", bytes_trfd);
        //print_bytes(data_buff, bytes_trfd);
        
        /* Parse the packet */
        *p_p_init_pkt = unmarshall_init_pkt(data_buff);
        
        // Check to see if we're getting the handshake again
        if ((*p_p_init_pkt)->hdr.seq_num == HS_SEQ_NUM) {
            send_ack(sock_num, p_cli_addr, HS_SEQ_NUM, ACK_PKT_TYPE);
        }
        
        if ((*p_p_init_pkt)->hdr.chk_sum != 0) {
            //debug_min("recv_init(): p_init_pkt->hdr.chk_sum = %hu\n", (*p_p_init_pkt)->hdr.chk_sum);
            //print_sockaddr_info(p_cli_addr);
            // NAK the packet
            send_ack(sock_num, p_cli_addr, INIT_SEQ_NUM, NAK_PKT_TYPE);
            return RES_DATA_CORRUPT;
        }
        
        /* Try to open the file */
        *p_p_file = fopen((*p_p_init_pkt)->filename, "w+");
        if (*p_p_file == NULL) {
            perror("Could not open file for writing");
            send_ack(sock_num, p_cli_addr, INIT_SEQ_NUM, FILE_ERR_PKT_TYPE);
            return RES_FILE_ERR;
        }
        
        /* Send positive acknowledgement */
        send_ack(sock_num, p_cli_addr, INIT_SEQ_NUM, ACK_PKT_TYPE);
        result = RES_SUCCESS;
        //debug_max("recv_init(): result = %i\n", result);    
    } else {
        //debug_medium("recv_int(): did not find any data to receive\n");
    }
    
    return result;
}
示例#5
0
文件: UDP.cpp 项目: arip33/AudioFiles
/** Identifies who is calling 
 *
 * @return the uid of the person calling when successful, else 0
 */
uint32_t UDP::getCallerID() {
   int status, rec_size;
   packet initPacket;

   status = select_call(&socket_num, 1, INIT_TIMEOUT, 0);
   if (status) {
      rec_size = recvfrom(socket_num, (void *) &initPacket, sizeof(packet), 0,
            (struct sockaddr *) &client_addr, &client_addr_len);
      if (rec_size == 0) {
#ifdef DEBUG
         cerr << "getCallerID: socket_num shutdown\n";
#endif
      } else if (rec_size != sizeof(packet)) {
         perror("recv()");
      } else {
         return ntohl(initPacket.uid);
      }
   }

   return 0;
}
示例#6
0
文件: rcopy.c 项目: jtdreisb/networks
STATE filename(char *fname, int32_t buf_size, int32_t window_size)
{
	uint8_t buf[MAX_PACKET_LEN];
	uint8_t flag = 0;
	uint32_t seq_num = 0;
	int32_t fname_len = strlen(fname) + 1;
	int32_t recv_check = 0;

	buf_size = htonl(buf_size);
	memcpy(buf, &buf_size, 4);
	window_size = htonl(window_size);
	memcpy(&buf[4], &window_size, 4);
	memcpy(&buf[8], fname, fname_len);

	send_buf(buf, fname_len + 8, &server, FLAG_FILENAME_REQ, 0);

	if (select_call(server.socket_num, 1, 0, NOT_NULL) == 1) {
		recv_check = recv_buf(buf, MAX_PACKET_LEN, server.socket_num, &server, &flag, &seq_num);

		if (recv_check == CRC_ERROR) {
			return STATE_FILENAME;
		}

		switch (flag) {
			case FLAG_FILENAME_RESP_OK:
				return STATE_FILE_OK;
				break;
			case FLAG_FILENAME_RESP_BAD:
				printf("File (%s) not found on server\n", fname);
				exit(1);
				break;
			default:
				break;
		}
	}

	return STATE_FILENAME;
}
int Client::recvPacket(packet &buf) {
    #ifndef DEBUG_CHLD
        // Check for timeout
        if (select_call(mvSocket, 1, 0) == 0) {
            std::cerr << "Server timed out.  Retries left: " << mvRetries--
                      << std::endl;
            return 2;
        }
        
        mvRetries = PKT_TRNSMAX;
    #endif

    // Receive packets
    if (recvfrom(mvSocket, &buf, sizeof(packet), 0,
                 (sockaddr *)&mvAddr, &mvAddrLen) == -1) {
        std::cerr << "recvfrom (" << __LINE__ << "): " << strerror(errno)
                  << std::endl;
        return 1;
    }
    
    // Verify packet checksum
    uint16_t ck = buf.checksum;
    buf.checksum = 0;

    if ((buf.checksum = in_cksum((unsigned short*)&buf, sizeof(packet)))
        != ck) {
        std::cerr << "Received packet with bad checksum.  Expected 0x"
                  << std::hex << ck << ", received 0x" << std::hex
                  << buf.checksum << std::endl
                  << "Sequence: " << std::dec << buf.sequence << std::endl
                  << "Retries left: " << std::dec << mvRetries-- << std::endl;
        return 2;
    }
    
    return 0;
}
示例#8
0
文件: rcopy.c 项目: jtdreisb/networks
STATE recv_data(Window *window)
{
	uint32_t seq_num = 0;
	uint8_t flag = 0;
	int32_t data_len = 0;
	uint8_t data_buf[MAX_PACKET_LEN];

	uint32_t window_index;
	uint32_t buffer_offset;
	uint32_t next_seq_num;
	uint32_t max_seq_num;

	static uint32_t expected_seq_number = 0;

	if (select_call(server.socket_num, 10, 0, NOT_NULL) == 0) {
		fprintf(stderr, "Shutting down: No response from server for 10 seconds.\n");
		exit(1);
	}

	data_len = recv_buf(data_buf, MAX_PACKET_LEN, server.socket_num, &server, &flag, &seq_num);

	if (data_len == CRC_ERROR) {
		return STATE_RECV_DATA;
	}

	switch (flag) {
		case FLAG_DATA:
		case FLAG_DATA_RESENT:

			max_seq_num = maxSequenceNumber(window);
			next_seq_num = nextOpenSequenceNumber(window);

			// printf("PACKET: seq_num: %u max: %u next: %u exp: %u\n", seq_num, max_seq_num, next_seq_num, expected_seq_number);

			if (seq_num < next_seq_num) {
				if (seq_num < window->base_seq_num) {
					send_ack(window->base_seq_num-1);
				}
				else {
					if (windowIsFull(window)) {
						send_ack(max_seq_num);
					}
					else {
						send_srej(next_seq_num);
					}
				}
				break;
			}

			// See if the seq_num falls within this windows range
			if ((seq_num >= window->base_seq_num) && (seq_num < (window->base_seq_num + window->window_size))) {
				window_index = (seq_num-1) % window->window_size;
				// Save data if it isn't already in there
				if (window->registry[window_index] == 0) {

					buffer_offset = window_index * window->block_size;
					memcpy(&window->buffer[buffer_offset], data_buf, data_len);

					// Mark the window as received
					window->registry[window_index] = 1;

					max_seq_num = maxSequenceNumber(window);
					next_seq_num = nextOpenSequenceNumber(window);

					if (seq_num == max_seq_num) {
						window->buffer_size = buffer_offset + data_len;
					}
				}
			}


			if (seq_num > next_seq_num) {
				// the previous sequence number
				window_index = ((seq_num-1) % window->window_size);
				if (window->registry[window_index-1] == 0) {
					send_srej(window->base_seq_num+window_index-1);
				}
			}
			else {
				send_ack(next_seq_num-1);
			}

			expected_seq_number = next_seq_num;

			if (windowIsFull(window)) {
				// printf("Window Full\n");
				return STATE_WINDOW_FULL;
			}

			break;

		case FLAG_END_OF_FILE:
			// printf("GOT EOF: seq_num: %u\n", seq_num);// !!!
			return STATE_EOF;
			break;

		default:
			break;

	}

	return STATE_RECV_DATA;
}
示例#9
0
文件: server.c 项目: AsBeug/Shoool
/**
 * Implement Go-Back-N sliding windows to receive the data packets.
 **/
void recv_file(int sock_num, struct sockaddr_in * p_cli_addr, u_int file_len, u_int buffer_sz, FILE * p_file) {
    u_int   last_pkt_ackd = INIT_SEQ_NUM;
    u_int   next_pkt = last_pkt_ackd + 1;
    u_int   total_seqs = ((int) ceil((double) file_len / (double) buffer_sz)) + INIT_SEQ_NUM;
    
    //debug_max("------------- receive file -------------\n");
    //debug_max("recv_file(): total_seqs = %i\n", total_seqs);
    
    /* Start receiving packets */
    data_pkt_t * p_data_pkt = NULL;
    
    int i = 0;
    
    while (next_pkt <= total_seqs) { // we still have packets to receive
        i++;
        //debug_max("recv_file(): round = %i\n", i);
        //debug_max("recv_file(): next_pkt = %i <= total_seq = %i\n", next_pkt, total_seqs);
        
        if (select_call(sock_num, SRV_WAIT_SECS, 0)) {
            p_data_pkt = recv_data(sock_num, p_cli_addr);
            
            //debug_max("\trecv_file(): p_data_pkt->hdr.chk_sum = %i\n", p_data_pkt->hdr.chk_sum);
            //debug_max("\trecv_file(): p_data_pkt->hdr.seq_num = %i -v- next_pkt = %i\n", p_data_pkt->hdr.seq_num, next_pkt);

            if (p_data_pkt->hdr.chk_sum !=0 ) {
                // packet is corrupt, don't use
                //debug_max("\trecv_file(): check sum error\n");
                send_ack(sock_num, p_cli_addr, next_pkt, NAK_PKT_TYPE);
            } else if (p_data_pkt->hdr.seq_num == next_pkt) {
                // this is the one we're looking for
                // check the check sum to decide what to do
                //debug_max("\trecv_file(): send ack seq_num = %i\n", p_data_pkt->hdr.seq_num);
                // packet is uncorrupted, write to file and ACK
                fwrite(p_data_pkt->data, sizeof(char), p_data_pkt->hdr.buffer_sz, p_file);
                send_ack(sock_num, p_cli_addr, p_data_pkt->hdr.seq_num, ACK_PKT_TYPE);
                last_pkt_ackd = p_data_pkt->hdr.seq_num;
                next_pkt = last_pkt_ackd + 1;
            } else if (p_data_pkt->hdr.seq_num == 1) {
                // catch the case where the init packet gets resent
                // and simply re-ACK
                send_ack(sock_num, p_cli_addr, INIT_PKT_TYPE, ACK_PKT_TYPE);
            } else if (p_data_pkt->hdr.seq_num < next_pkt) { 
                // we've already seen, re-ack
                //debug_max("\t\trecv_file(): re-acking %i\n", p_data_pkt->hdr.seq_num);
                send_ack(sock_num, p_cli_addr, last_pkt_ackd, ACK_PKT_TYPE);
            } else {    
                // too high, we must have missed one, NAK what we were looking for
                //debug_max("\t\trecv_file(): NAKing... p_data_pkt->hdr.chk_sum = %hu\n", p_data_pkt->hdr.chk_sum);
                send_ack(sock_num, p_cli_addr, next_pkt, NAK_PKT_TYPE);
            }
            
        } else {
            // heard nothing from the client
            debug_errors("recv_file(): heard nothing from client; exiting\n");
            break;
        }
        
    }
    
    debug_print("recv_file(): finished receiving file from client\n");
}