Feat: FTP 서버 기본 구조 구현

- AndroidManifest.xml에 필요한 권한 추가 (INTERNET, STORAGE 등)
- FTPResponse 클래스 생성: FTP 응답 코드 상수 정의
- FTPSession 클래스 생성: 개별 클라이언트 세션 처리
  * 명령어 읽기/응답 보내기 기본 루프
  * USER, PASS, QUIT, SYST, PWD, NOOP 명령어 처리
- FTPServer 클래스 생성: 메인 서버 로직
  * ServerSocket으로 포트 2121에서 수신 대기
  * ExecutorService로 다중 클라이언트 연결 관리
- FTPService 클래스 생성: 백그라운드 포그라운드 서비스
  * 서버 시작/중지 Intent 처리
  * 알림 채널 및 포그라운드 서비스 구현
- MainActivity UI 업데이트: 서버 제어 기능
  * 시작/중지 버튼 추가
  * 서버 상태 표시
  * 런타임 권한 요청 처리

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-01 02:46:18 +09:00
parent 509685936a
commit f08d8d66d8
50 changed files with 1459 additions and 0 deletions

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/titleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android FTP Server"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="32dp" />
<TextView
android:id="@+id/statusTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Server Status: Stopped"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleTextView"
android:layout_marginTop="24dp" />
<TextView
android:id="@+id/portTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Port: 2121"
android:textSize="14sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/statusTextView"
android:layout_marginTop="8dp" />
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start Server"
android:minWidth="150dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/portTextView"
android:layout_marginTop="32dp" />
<Button
android:id="@+id/stopButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop Server"
android:minWidth="150dp"
android:enabled="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/startButton"
android:layout_marginTop="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>