코딩 일지

VPN 앱 제작기 #1

아는맛이무섭다 2024. 2. 1. 17:36

오늘 강의 완주를 끝내고, 머리를 식힐겸 새롭게 앱을 하나 제작해보기로 했습니다.

가장 많이 쓰일 앱이 무엇일지 플레이스토어를 둘러봤어요.

 

그러다가 VPN 앱이 눈에 들어와서 한번 제작 해보기로 마음을 먹었습니다.

 

 

저는 제 VPN앱 이름을 Omega VPN으로 결정했고, 검색해봤는데 아직 없어서 제작하기로 했습니다.

이 VPN 앱이 꺼져도 여전히 뒤에서 백그라운드에서 돌아가야하기 때문에 서비스?라는 기능을 이용해야하더라고요.

그래서 MainActivity 파일 말고, MyVpnService.kt 로 파일을 하나더 만들어줬습니다.

 

MyVpnService.kt

더보기

import android.app.Notification
import android.app.PendingIntent
import android.content.Intent
import android.net.VpnService
import android.os.ParcelFileDescriptor
import android.util.Log
import androidx.core.app.NotificationCompat
import java.io.FileInputStream
import java.io.FileOutputStream
import java.nio.ByteBuffer

class MyVpnService : VpnService() {

private val TAG = "MyVpnService"
private var vpnInterface: ParcelFileDescriptor? = null

override fun onCreate() {
super.onCreate()
Log.i(TAG, "onCreate")
Thread {
try {
// VPN 인터페이스 설정
vpnInterface = establishVPN()

// 네트워크 트래픽을 VPN으로 전송하는 로직
processNetworkTraffic()

} catch (e: Exception) {
e.printStackTrace()
} finally {
vpnInterface?.let {
try {
it.close()
} catch (e: Exception) {
e.printStackTrace()
}
}
}
}.start()
}

private fun establishVPN(): ParcelFileDescriptor? {
val builder = Builder()
builder.addAddress("10.0.0.2", 32)
builder.addRoute("0.0.0.0", 0)
builder.addDnsServer("8.8.8.8")
builder.addDnsServer("8.8.4.4")

return builder.establish()
}

private fun processNetworkTraffic() {
vpnInterface?.let {
try {
FileInputStream(it.fileDescriptor).use { `in` ->
FileOutputStream(it.fileDescriptor).use { out ->
// VPN 트래픽을 처리하는 로직
val packet = ByteBuffer.allocate(32767)
while (true) {
packet.clear()
val length = `in`.read(packet.array())
if (length > 0) {
packet.limit(length)
processPacket(packet)
out.write(packet.array(), 0, length)
}
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}

private fun processPacket(packet: ByteBuffer) {
// 패킷 처리 로직
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_STICKY
}

private fun buildNotification(): Notification {
val notificationIntent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE
)

val notification = NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("VPN Service")
.setContentText("VPN Service is running")
.setSmallIcon(R.drawable.ic_key) // 열쇠 모양의 아이콘을 사용하려면 해당 이미지를 drawable 폴더에 추가해야 합니다.
.setContentIntent(pendingIntent)
.build()

return notification
}

companion object {
private const val ONGOING_NOTIFICATION_ID = 1
private const val CHANNEL_ID = "VPN_CHANNEL"
}
}

 

VPN을 실행하면 화면 상단에 열쇠모양같은 표시가 있으면 편해서 그 기능도 넣어보았습니다.

이제 서버를 구축하고 VPN 서비스를 이용할 수 있게 또 다시 구축해야하는데, 어떻게 해야할지 감이 약간 안 잡히네요.

제가 제 첫 앱을 VPN 서비스 앱으로 하게 될줄은 몰랐지만, 조금 신나기도 하네요.

 

무료 영어레벨테스트 앱을 먼저 개발할지, VPN 앱을 먼저 개발할지 둘 중 고민 끝에서 VPN앱을 먼저 개발하게 되었습니다. 영어레벨테스트 앱은 조금 더 확장시켜서 영어 교육 앱을 한번 만들어보고 싶은 욕심이 조금 있어서 조금 더 확장시켜서 기획하고 있습니다.

 

VPN앱은 화면 많이 많들지 않고 작동만 시키면 끝인 걸로 단순하게 만들려고 합니다 Activity는 많아봐야 3개만 만들려고 하고, 옆에 메뉴화면도 만들어보고 싶어서 지금 ChatGPT에게 일을 시키고 있습니다.

 

MainActivity.kt

더보기

import android.content.Intent
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val startVpnButton: Button = findViewById(R.id.startVpnButton)
startVpnButton.setOnClickListener {
startVpnService()
}
}

private fun startVpnService() {
val vpnIntent = Intent(this, MyVpnService::class.java)
startService(vpnIntent)
}

activity_main.xml

더보기

xml 기타,...

 

<Button
android:id="@+id/startVpnButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginBottom="301dp"
android:text="Start VPN"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />

지금은 버튼 딱 하나인 상태에서 누르면 아무런 작동이 안되는 상태입니다. 우선 VPN 서버 구축은 어떻게 해야하는지부터 시작해야겠네요. 나중에 알고리즘이나 AI도 한번 만들어서 앱에 작동시켜보고 싶네요.

 

 

디자인도 시간을 많이 투자하지 않고 적당히 깔끔하게 아이콘 만들어서 작업할까 합니다.

내일은 질문지 코딩에 대해서 포스팅을 올리겠습니다. 

그럼 좋은 하루 되세요!

'코딩 일지' 카테고리의 다른 글

창고앱 구현 #1 + 안드로이드 스튜디오 앱 로고 바꾸기  (2) 2024.02.28
코틀린 배운 후기  (2) 2024.02.08
코틀린 기초문법  (3) 2024.02.06
초보의 앱개발  (2) 2024.01.25
앱스타터  (0) 2024.01.24