코드

#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int ConnectToServer(char *hostname, char * pnum, char *filename);
int ParseResponse(int sd, char *fname);


int main(int argc, char *argv[]) {
	int socktoserver = -1;
	if (argc != 4) {
		printf("Wrong command\n");
		printf("hw1 host port file\n");
		return 0;
	}
	printf("Student ID : 12345\n");
	printf("Name : heeyeon\n");

	char *hostname = argv[1];
	char *pnum = argv[2];
	char *filename = argv[3];

	char fname[BUFSIZ];

	socktoserver = ConnectToServer(hostname, pnum, filename);
	if(socktoserver < 0) {
		exit(0);
	}

	char *realname = strrchr(filename, '/');
	if (realname == NULL)
		strcpy(fname, filename);
	else
		strcpy(fname, realname + 1);

	ParseResponse(socktoserver, fname);
} 



int ConnectToServer(char *hostname, char * pnum, char *filename) {
	int socktoserver;
	struct sockaddr_in server;

	if ((socktoserver = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		perror("socket");
		exit(1);
	}

	struct hostent *hostp;

	if ((hostp = gethostbyname(hostname)) == 0) {
		fprintf(stderr,"%s: unknown host\n", hostname);
		return -1;
	}

	memset((void *) &server, 0, sizeof server); 
	server.sin_family = AF_INET;
	memcpy((void *) &server.sin_addr, hostp->h_addr, hostp->h_length);
	server.sin_port = htons((u_short)atoi(pnum));

	if (connect(socktoserver, (struct sockaddr *)&server, sizeof server) < 0) {
		return -1;
	}

	char msg[BUFSIZ];
	sprintf(msg, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-agent: webcli/1.0\r\nConnection: close\r\n\r\n", filename, hostname);
	if(write(socktoserver, msg, strlen(msg)) < 0) {
		perror("write");
		exit(1);
	}

	return socktoserver;
}


int ParseResponse(int sd, char *fname) { 

	char buf[BUFSIZ];
	FILE *fpSock = fdopen(sd, "r");

	unsigned int numread = 0;
	unsigned int numtoread = 0;

	while(1) {
		if (fgets(buf, BUFSIZ - 1, fpSock) != NULL) {
			if(strcmp(buf, "\r\n") == 0) {
				break;
			} else if(strncmp(buf, "HTTP/", 5) == 0) {
				char *field = strtok(buf, " ");
				char *value = strtok(NULL, " ");
				char *rest = strtok(NULL, "");
				int val = atoi(value);
				if(val != 200) {
					printf("%s %s\n", value, rest);
					fclose(fpSock);
					return -1;
				}
			} else {
				char *field = strtok(buf, ":");
				char *value = strtok(NULL, " \t\n\r");
				if(strcmp(field, "Content-Length") == 0) {
					numtoread = atoi(value); 
					printf("Total Size %d bytes\n", numtoread);
				} 
				printf("%s %s\n", field, value);
			} 
		}
		else {
			printf("input error");
			return 0;
		}
	}  

	// now, open the file write
	FILE *fp = fopen(fname, "w+");
	if(fp == NULL) {
		printf("File Open Fail %s", fname);
	}

	unsigned int step = 1;
	while(1) {
		int nread = fread(buf, sizeof(char), BUFSIZ - 1, fpSock);
		if( nread <= 0)
			break;
		numread += (unsigned int)nread;
		fwrite(buf, sizeof(char), nread, fp);
		unsigned int fill = (unsigned int)numread * 10 / numtoread;
		if(fill >= step) {
			printf("Current Downloading %d/%d (bytes) %.0f%%\n", 
				numread, numtoread, (float)numread / numtoread * 100);
			step = fill + 1;
		}
	}		
	fclose(fpSock);
	fclose(fp);
	printf("Download Complete: %s, %d/%d\n",
		fname, numread, numtoread);
	return 1;
}

실습 내용

1개의 댓글

comment-user-thumbnail
2024년 4월 10일

안녕하세요 ! 혹시 과제에 대해서 질문좀 드려도 될까요 ?

답글 달기