#include #include #include #include #include #include #include #include #include #include char sockmode_exist[] = "EXIST"; // 파일이 있는지, 없는지 판별하기 위해 전송할 문자열 char sockmode_error[] = "ERROR"; int main () { int server_sockfd, client_sockfd; unsigned int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; char fname[256]="", fncount=0, *filecontent=NULL; // 파일이름, 파일이름길이, 파일내용 FILE *fp=NULL; // 파일 핸들 long filesize=0; // 파일크기 struct stat statbuf; // 파일크기를 얻어오기 위한 구조체 server_sockfd = socket (AF_INET, SOCK_STREAM, 0); server_address.sin_family = AF_INET; server_address.sin_addr.s_addr = inet_addr ("127.0.0.1"); server_address.sin_port = 9734; server_len = sizeof (server_address); bind (server_sockfd, (struct sockaddr *)&server_address, server_len); listen (server_sockfd, 5); while (1) { printf ("server waiting\n"); client_sockfd = accept (server_sockfd, (struct sockaddr *)&client_address, &client_len); if (client_sockfd == -1) { printf ("oops! connection failed.\n"); continue; } while (1) { // #quit 메시지가 클라이언트에서 전송될때까지 계속 반복시킵니다. memset (fname, 0, 256); // 파일명을 깨끗이 합니다. read (client_sockfd, &fncount, 1); // 파일명 길이를 읽어옵니다. read (client_sockfd, fname, fncount); // 파일명을 얻어옵니다. printf ("%s is requested.(size %d)\n", fname, fncount); // 제대로 파일이름을 얻었는지 확인 if (strncmp (fname, "#quit", fncount) == 0) break; // 파일이름이 #quit로 오면, 접속을 끊습니다. fp = fopen (fname, "r"); // 파일이름이 제대로 되어있다면, 로컬파일을 열어서 if (fp == NULL) { printf ("fopen error!\n"); break; } fstat (fileno (fp), &statbuf); // 로컬파일 정보를 구합니다. (파일 크기를 얻기 위해서) filecontent = malloc (statbuf.st_size); // 얻어온 파일길이로 메모리를 할당하고, if (fread (filecontent, 1, statbuf.st_size, fp) == statbuf.st_size) { // 변수로 얻은 길이만큼 로컬파일에서 읽습니다. (성공하면) write (client_sockfd, sockmode_exist, 6); // 파일이 잘 있다고 알려주고 write (client_sockfd, &filesize, sizeof(long)); // 파일 크기를 전송해준 뒤에 write (client_sockfd, filecontent, filesize); // 파일내용을 보내줍니다. } else { // (파일내용을 읽는데 실패하면) write (client_sockfd, sockmode_error, 6); // 파일이 없어서 에러가 났다고 알려줍니다. } free (filecontent); // 할당한 메모리를 제거하고 fclose (fp); // 파일을 닫습니다. } close (client_sockfd); } }