Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

FTP 서버/클라이언트 구현 프로젝트

📋 프로젝트 개요

이 프로젝트는 FTP(File Transfer Protocol) 서버와 클라이언트를 C 언어를 사용하여 구현한 시스템 프로그래밍 과제입니다. TCP/IP 소켓 프로그래밍을 기반으로 하며, 표준 FTP 명령어를 지원하는 완전한 FTP 서비스 시스템을 제공합니다.

작성자: 김준원
작성일: 2024/05/28
운영체제: Ubuntu 20.04.06 LTS 64bits


✨ 주요 기능

클라이언트 (cli.c)

  • ✅ 서버 연결 및 사용자 인증
  • ✅ FTP 명령어 변환 (사용자 명령 → FTP 명령)
  • ✅ 파일 목록 조회 (ls, ls -a, ls -l, ls -al)
  • ✅ 현재 작업 디렉토리 확인 (pwd)
  • ✅ 디렉토리 이동 (cd, cd ..)
  • ✅ 디렉토리 생성/삭제 (mkdir, rmdir)
  • ✅ 파일 삭제 (delete)
  • ✅ 파일 이름 변경 (rename)
  • ✅ 파일 다운로드 (get)
  • ✅ 파일 업로드 (put)
  • ✅ 전송 모드 설정 (bin, ascii, type binary, type ascii)
  • ✅ 프로그램 종료 (quit)
  • ✅ 데이터 연결(PORT 모드) 자동 생성 및 관리
  • ✅ 전송된 파일 크기 표시

서버 (srv.c)

  • ✅ 동시 다중 클라이언트 지원 (Concurrent Server)
  • ✅ IP 주소 기반 접근 제어 (access.txt)
  • ✅ 사용자 인증 (passwd 파일 기반)
  • ✅ 로그인 실패 3회 제한
  • ✅ 모든 FTP 명령어 처리 및 실행
  • ✅ 데이터 연결 분리 (Control/Data Connection)
  • ✅ 바이너리/ASCII 전송 모드 지원
  • ✅ 파일 시스템 연동 (디렉토리 탐색, 파일 조작)
  • ✅ KILL 신호(^C) 처리

🔧 시스템 요구사항

필수 요구사항

  • 운영체제: Linux/Unix (Ubuntu 20.04 이상 권장)
  • 컴파일러: GCC
  • 라이브러리: 표준 C 라이브러리
  • 네트워크: TCP/IP 지원

필요한 헤더 파일

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>

📁 프로젝트 구조

Assignment3_3_D_2020202095/
│
├── cli.c              # FTP 클라이언트 소스 코드
├── srv.c              # FTP 서버 소스 코드
├── Makefile           # 빌드 스크립트
├── access.txt         # IP 접근 제어 파일
├── passwd             # 사용자 인증 파일
├── ARCHITECTURE.md    # 시스템 아키텍처 문서
└── README.md          # 프로젝트 설명서 (본 파일)

주요 파일 설명

cli.c

  • FTP 클라이언트 프로그램
  • 사용자 입력을 받아 FTP 명령으로 변환하고 서버로 전송
  • 서버 응답을 처리하여 결과를 출력

srv.c

  • FTP 서버 프로그램
  • 클라이언트 연결을 받아 인증 후 명령 처리
  • fork()를 사용한 동시 다중 클라이언트 지원

access.txt

  • 허용할 IP 주소 패턴 목록
  • 와일드카드(*) 지원
  • 예시:
    127.0.0.1
    128.134.64.*
    203.245.*.*
    

passwd

  • 사용자 인증 정보 저장 파일
  • /etc/passwd 형식으로 구성
  • 사용자명과 비밀번호 검증에 사용

🚀 빌드 및 실행 방법

1. 프로젝트 빌드

# 모든 프로그램 빌드
make

# 또는 개별 빌드
make cli    # 클라이언트만 빌드
make srv    # 서버만 빌드

빌드 결과:

  • cli: 클라이언트 실행 파일
  • srv: 서버 실행 파일

2. 빌드 파일 정리

make clean  # 생성된 실행 파일 삭제

3. 서버 실행

# 기본 사용법
./srv [포트번호]

# 예시: 포트 2121에서 서버 실행
./srv 2121

서버 실행 시 주의사항:

  • 서버는 지정된 포트에서 대기 상태로 시작됩니다
  • 클라이언트 연결을 기다립니다
  • KILL 신호(^C)로 종료합니다

4. 클라이언트 실행

# 기본 사용법
./cli [서버IP] [포트번호]

# 예시: 로컬 서버(포트 2121)에 연결
./cli 127.0.0.1 2121

클라이언트 실행 후:

  1. 서버에서 접근 제어 확인 → Welcome 메시지 또는 거부 메시지
  2. 사용자명 입력 (Input ID :)
  3. 비밀번호 입력 (Input Password :)
  4. 로그인 성공 시 ftp> 프롬프트 표시
  5. FTP 명령어 입력

📝 명령어 참조

디렉토리 및 파일 조회

ls

현재 디렉토리의 파일 목록을 간단히 표시합니다.

ftp> ls
file1.txt
file2.txt
directory1/

ls -a

숨김 파일을 포함한 모든 파일을 표시합니다.

ftp> ls -a
./
../
file1.txt
.hidden_file

ls -l

파일의 상세 정보를 표시합니다 (권한, 소유자, 크기, 수정일 등).

ftp> ls -l
-rw-r--r--    1 user group    1024 May 28 10:00 file1.txt
drwxr-xr-x    2 user group    4096 May 28 10:01 directory1/

ls -al 또는 ls -la

숨김 파일을 포함한 상세 정보를 표시합니다.

pwd

현재 작업 디렉토리의 절대 경로를 표시합니다.

ftp> pwd
257 "/home/user/ftp" is current directory

디렉토리 이동 및 생성/삭제

cd [경로]

지정한 디렉토리로 이동합니다.

ftp> cd directory1
250 CWD command suceeds.

cd ..

상위 디렉토리로 이동합니다.

ftp> cd ..
250 CWD command suceeds.

mkdir [디렉토리명]

새 디렉토리를 생성합니다.

ftp> mkdir newdir
250 MKD command performed successfully.

rmdir [디렉토리명]

빈 디렉토리를 삭제합니다.

ftp> rmdir olddir
250 RMD command performed successfully.

파일 조작

delete [파일명]

파일을 삭제합니다.

ftp> delete file.txt
250 DELE command performed succesfully

rename [기존이름] [새이름]

파일 또는 디렉토리 이름을 변경합니다.

ftp> rename old.txt new.txt
350 File exists, ready to rename
250 RNTO command succeeds

파일 전송

get [파일명]

서버에서 파일을 다운로드합니다.

ftp> get file.txt
150 Opening binary mode data connection.
226 Complete transmission.
OK. 1024 bytes is received.

put [파일명]

클라이언트에서 서버로 파일을 업로드합니다.

ftp> put localfile.txt
150 Opening binary mode data connection.
226 Complete transmission.
OK. 2048 bytes sent.

전송 모드 설정

bin 또는 type binary

바이너리 모드로 전환합니다 (기본값).

ftp> bin
201 Type set to I.

ascii 또는 type ascii

ASCII 텍스트 모드로 전환합니다.

ftp> ascii
201 Type set to A.

종료

quit

FTP 세션을 종료하고 클라이언트 프로그램을 종료합니다.

ftp> quit
221 Goodbye.

🏗️ 시스템 아키텍처

연결 구조

이 FTP 구현은 분리된 연결(Split Connection) 방식을 사용합니다:

  1. Control Connection (제어 연결)

    • 포트: 사용자 지정 (예: 2121)
    • 용도: FTP 명령어 전송 및 응답 수신
    • 프로토콜: TCP/IP
  2. Data Connection (데이터 연결)

    • 포트: 동적으로 생성 (10001~30000 범위의 랜덤 포트)
    • 용도: 파일 데이터 및 디렉토리 목록 전송
    • 프로토콜: TCP/IP
    • 생성 방식: PORT 모드 (클라이언트가 서버에 포트 정보 제공)

동시성 처리

서버는 Concurrent Server 방식으로 구현되었습니다:

  • fork() 시스템 콜을 사용하여 각 클라이언트마다 별도의 자식 프로세스 생성
  • 부모 프로세스는 새로운 연결을 계속 수락
  • 자식 프로세스는 해당 클라이언트의 명령을 처리

인증 프로세스

1. 클라이언트 연결 요청
   ↓
2. 서버: IP 주소 확인 (access.txt)
   ├─ 허용된 IP → Welcome 메시지 (220)
   └─ 거부된 IP → 접근 거부 메시지 (431) 및 연결 종료
   ↓
3. 클라이언트: USER [사용자명] 전송
   ↓
4. 서버: 사용자명 확인 (passwd 파일)
   ├─ 유효 → 331 Password required
   └─ 무효 → 430 Invalid username → 재시도 (최대 3회)
   ↓
5. 클라이언트: PASS [비밀번호] 전송
   ↓
6. 서버: 비밀번호 확인 (passwd 파일)
   ├─ 유효 → 230 User logged in
   └─ 무효 → 430 Invalid password → 재시도 (최대 3회)
   ↓
7. 세션 시작 (fork()로 자식 프로세스 생성)

명령 처리 흐름

1. 클라이언트: 사용자 명령 입력 (예: "ls -l")
   ↓
2. 클라이언트: FTP 명령으로 변환 ("NLST -l")
   ↓
3. [데이터 연결 필요한 경우]
   - 클라이언트: 데이터 소켓 생성 및 대기
   - 클라이언트: PORT 명령으로 포트 정보 전송
   - 서버: 200 Port command successfully
   - 서버: 클라이언트의 데이터 소켓에 연결
   ↓
4. 클라이언트: 변환된 FTP 명령 전송
   ↓
5. 서버: 명령 파싱 및 실행
   ↓
6. 서버: 실행 결과를 데이터 연결로 전송 (또는 제어 연결로 응답)
   ↓
7. 서버: 완료 메시지 전송 (226 Complete transmission)
   ↓
8. 클라이언트: 결과 출력 및 데이터 연결 종료

🔐 보안 및 접근 제어

IP 접근 제어

access.txt 파일에 허용할 IP 주소 패턴을 작성합니다.

형식:

  • 정확한 IP: 127.0.0.1
  • 와일드카드 사용: 128.134.64.* (128.134.64.0~255 허용)
  • 다중 와일드카드: 203.245.*.*

예시 파일:

127.0.0.1
128.134.64.*
128.134.57.*
128.134.54.171
203.245.*.*
*.*.0.1

사용자 인증

passwd 파일을 사용하여 사용자를 인증합니다. 이 파일은 시스템의 /etc/passwd 파일 형식을 따릅니다.

인증 방식:

  • 사용자명과 비밀번호를 평문으로 비교 (실제 시스템과 달리 암호화되지 않음)
  • 로그인 실패 시 최대 3회까지 재시도 가능
  • 3회 실패 시 세션 종료 (530 Failed to log-in)

🔄 FTP 명령어 변환 테이블

사용자 명령 FTP 명령 설명
ls NLST 파일 목록 (이름만)
ls -a NLST -a 숨김 파일 포함 목록
ls -l NLST -l 상세 정보 포함 목록
ls -al NLST -al 숨김 파일 포함 상세 목록
dir LIST 디렉토리 상세 목록
pwd PWD 현재 작업 디렉토리
cd [경로] CWD [경로] 디렉토리 변경
cd .. CDUP 상위 디렉토리로 이동
mkdir [이름] MKD [이름] 디렉토리 생성
rmdir [이름] RMD [이름] 디렉토리 삭제
delete [이름] DELE [이름] 파일 삭제
rename [old] [new] RNFR [old]
RNTO [new]
파일 이름 변경 (2단계)
get [파일] RETR [파일] 파일 다운로드
put [파일] STOR [파일] 파일 업로드
bin TYPE I 바이너리 모드
ascii TYPE A ASCII 모드
type binary TYPE I 바이너리 모드
type ascii TYPE A ASCII 모드
quit QUIT 세션 종료

📊 FTP 응답 코드

이 구현에서 사용하는 주요 FTP 응답 코드:

코드 의미 사용 시점
150 데이터 연결 열림 파일 전송 또는 목록 전송 시작 전
200 명령 성공 PORT 명령 성공 등
201 타입 설정 성공 TYPE 명령 성공
220 서비스 준비됨 서버 시작 시 Welcome 메시지
226 전송 완료 파일/목록 전송 완료
230 로그인 성공 인증 성공
250 파일 작업 성공 CWD, MKD, RMD, DELE 등 성공
257 경로명 표시 PWD 명령 응답
331 비밀번호 필요 USER 명령 후
350 파일 존재, 이름 변경 준비 RNFR 명령 후
430 잘못된 사용자명/비밀번호 인증 실패
431 접근 거부 IP 접근 제어 실패
502 명령 미구현 또는 오류 TYPE 명령 오류 등
550 파일/디렉토리 작업 실패 파일 없음, 권한 없음 등

About

2023-2 system programming project (FTP server)

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages