Пример #1
0
// Sends a termination message to the server
// @param sockfd the socket file descriptor
// @param server the server being sent to
// @param seq the sequence number of the message
// @param p a pointer to the filename
// @param client a pointer to the client variable
static void send_termination(int sockfd, host *server, int *seq, csv_record *p, client_info *client) {
    
    hftp_control_message *control = (hftp_control_message*)create_control_message(TERMINATE, *seq, p, client->token, 0);
    
    syslog(LOG_DEBUG, "Type: Termination, Sequence: %d", control->sequence);
    transmit(sockfd, (message**)&control, server, seq);
    
} //end send_termination
Пример #2
0
// Sends an intialize message to the server
// @param sockfd the socket file descriptor
// @param server the server being sent to
// @param seq the sequence number of the message
// @param file a pointer to the file variable
// @param client a pointer to the client variable
// @param hftpd a pointer to the server information
// @param p a pointer to the filename
// @param count the position in the list of files
static void send_initialize(int sockfd, host *server, int *seq, file_info *file,
                         client_info *client, server_info *hftpd, csv_record *p, int count) {
    
    hftp_control_message *control = (hftp_control_message*)create_control_message(INITIALIZE, *seq, p, client->token, file->file_length);
    
    syslog(LOG_INFO, "Transferring '%s' (%d of %d)", p->filename, count, get_list_length(client->response_list));
    syslog(LOG_DEBUG, "Type: Initialization, Sequence: %d, Filename length: %d", control->sequence, ntohs(control->filename_length));
    
    // Transmit a control request
    if (transmit(sockfd, (message**)&control, server, seq) == -1) {
        
        syslog(LOG_INFO, "Authentication with Hooli file transfer server failed");
        free_file_info(file);
        close(sockfd);
        
        free_server_info(hftpd);
        free_client_info(client);
        
        exit(EXIT_FAILURE);
        
    } //end if
    
} //end send_control
Пример #3
0
int main (int argc, char** argv)
{
	int c, i, sockfd;					// For switch and optind
	int seqNum = 0;						// Keep track of what's expected
	int timeout = 50;					// Default timeout
	char* hostname;						// Set by command line argument
	char* filename;						// Set by command line argument
	char* convert;						// To convert c-line timeout value to int
	char* port = "5000";				// Default		
	static int verbose_flag = 0;		// Set from command line
	host_t server;						// Address of the server
	control_message_t* ctrlMsg = NULL;	// Control messages received
	message_t* msg = NULL;				// Messages to send
	data_message_t* dataMsg = NULL;		// Data messages received

	while (1)
	{
		static struct option long_options[] =
		{
			{"verbose", no_argument, &verbose_flag, 1},
			{"timeout", required_argument, 0, 't'},
			{"port", required_argument, 0, 'p'},
			{0,0,0,0}
		};

		int option_index = 0;
		c = getopt_long(argc, argv, "vt:p:", long_options, &option_index);

		// If we've reached the end of the options, stop iterating
		if (c == -1)
			break;

		switch (c)
		{
			case 'v':
				verbose_flag = 1;
				break;

			case 't':
				convert = optarg;					// Save as char*
				sscanf(convert, "%d", &timeout);	// Convert to int for timeout
				break;

			case 'p':
				port = optarg;
				break;

			case '?':
                exit(EXIT_FAILURE);
                break;
		}
	}

	// Grab command line arguments
	i = optind;
	hostname = argv[i++];
	filename = argv[i];

	// Check that hostname and filename have been given
	if (hostname == NULL || filename == NULL)
	{
		printf("ERROR: Hostname and filename required\n");
		exit(EXIT_FAILURE);
	}

	// Get file size
	uint32_t fileSize = fsize(filename);

	// Print info
	printf("Transferring file: %s\nTotal size: %d bytes\n--------------------------------\n", filename, fileSize);

	// Filename length
	uint32_t fNameLength = sizeof(filename);

	// Create a socket and listen
	sockfd = create_client_socket(hostname, port, &server);

	// Encode the message
	msg = create_control_message(INITIATE, SEND, seqNum, fileSize, fNameLength, filename);

	// If timeout is reached  or seqNum of ACK is wrong then retransmit
	while (ctrlMsg == NULL || ctrlMsg->seqNum != 0)
	{
		// Send initial request 
		send_message(sockfd, msg, &server);
		if (verbose_flag)
			send_verbose(msg);
		ctrlMsg = (control_message_t*)receive_message_with_timeout(sockfd, timeout, &server);
	}
	free(msg);
	
	// Network order conversion and verbose check
	ctrlMsg->seqNum = ntohs(ctrlMsg->seqNum);
	if (verbose_flag == 1)
		ack_verbose((message_t*)ctrlMsg);
	free(ctrlMsg);

	// Type 1 ACK received
	FILE* fp = fopen(filename, "r");	// File to copy from
	int eof_flag = 1;					// For when eof is reached
	int bytes_transferred = 0;			// keep track of amount of data transferred

	// Until end of file is reached
	while (eof_flag != 0)
	{
		// Initialize array to zero
		char buffer[1464] = {};

		// Send data until fread returns 0
		eof_flag = fread(buffer, 1464, 1, fp);

		// Set length of data to send
		uint32_t dataLength = strlen(buffer);

		// Encode data message and set length
		seqNum = nextSeqNum(seqNum);
		msg = create_data_message(SEND, seqNum, dataLength, buffer);

		// Read response
		// If timeout is reached then retransmit
		while (dataMsg == NULL || dataMsg->seqNum != seqNum)
		{
			// Send and free its memory
			send_message(sockfd, msg, &server);
			if (verbose_flag)
				send_verbose(msg);
			dataMsg = (data_message_t*)receive_message_with_timeout(sockfd, timeout, &server);
			dataMsg->seqNum = ntohs(dataMsg->seqNum);
			if (verbose_flag)
				ack_verbose((message_t*)dataMsg);
		}
		free(msg);

		// Network order conversion and verbose check
		
		free(dataMsg);

		// Keep track of how much data transferred
		bytes_transferred += dataLength;
		int percent = (double)bytes_transferred/(double)fileSize*100;
			
		// Print info if percentge is multiple of 10
		if (percent % 10 == 0)
		{
			printf("--------------------------------\n");
			printf("Bytes transferred: %d\n", dataLength);
			printf("Total bytes transferred: %d\n", bytes_transferred);
			printf("Percentage complete: %d%%\n--------------------------------\n", percent);
		}
	}

	fclose(fp);
	seqNum = nextSeqNum(seqNum);
	msg = create_control_message(TERMINATE, SEND, seqNum, fileSize, fNameLength, filename);

	// Read final acknowledgment response
	// If timeout is reached then retransmit
	while (ctrlMsg == NULL || ctrlMsg->seqNum != seqNum)
	{
		// Send type 2 control message to signal eof has been reached
		send_message(sockfd, msg, &server);
		if (verbose_flag)
			send_verbose(msg);
		ctrlMsg = (control_message_t*)receive_message_with_timeout(sockfd, timeout, &server);
		ctrlMsg->seqNum = ntohs(ctrlMsg->seqNum);
		if (ctrlMsg->seqNum != seqNum)
			ctrlMsg = NULL;
	}
	free(msg);

	// Network order conversion and verbose check
	if (verbose_flag)
		ack_verbose((message_t*)ctrlMsg);

	free(ctrlMsg);
	close(sockfd);
	exit(EXIT_SUCCESS);
}