티스토리 뷰

반응형

서버와 클라이언트 간에 socket을 통해 통신하는 것을 socket 통신이라고 합니다.

 

 

 

서버 코드 작성하기

 

먼저 서버 코드를 작성하겠습니다.

 

fun main() {
    try {

        while (true) {
            
            val server = ServerSocket(7777)

            println("사용자 접속 대기중...")

            val socket = server.accept()

            val input = socket.getInputStream()
            val dataInputStream = DataInputStream(input)

            val output = socket.getOutputStream()
            val dataOutputStream = DataOutputStream(output)

            dataOutputStream.writeInt(7)
            dataOutputStream.writeUTF("서버 문자열")

            val intData = dataInputStream.readInt()
            val stringData = dataInputStream.readUTF()

            socket.close()
            server.close()

            println("Android 에서 받은 숫자 : $intData")
            println("Android 에서 받은 문자열 : $stringData")
        }

    } catch (e: Exception) {
        e.printStackTrace()
    }
}

 

코드에 대해서는 차례대로 설명하겠습니다.

 

 

먼저 서버 소켓의 객체를 생성해줍니다. ServerSocket 안에는 포트 번호를 넣어줍니다.

val server = ServerSocket(7777)

 

그리고 접속 대기를 알려주고 Socket을 연결해줍니다.

println("사용자 접속 대기중...")

val socket = server.accept()

 

Socket을 통해 데이터를 얻어오기 위해서 아래와 같이 작성해줍니다.

val input = socket.getInputStream()
val dataInputStream = DataInputStream(input)

 

그리고 데이터를 보내기 위해서 아래와 같이 작성해줍니다.

val output = socket.getOutputStream()
val dataOutputStream = DataOutputStream(output)

 

서버에서 먼저 데이터를 보내고 클라이언트에서는 나중에 데이터를 보내는 코드를 작성할 것입니다.

양쪽이 동시에 보내면 안 되기 때문에 한쪽이 보내면 데이터를 받는 식으로 코드를 작성해야 합니다.

 

클라이언트로 데이터를 보내는 코드를 작성하였습니다.

dataOutputStream.writeInt(7)
dataOutputStream.writeUTF("서버 문자열")

 

그리고 클라이언트로부터 받은 데이터를 출력하는 코드를 작성하였습니다.

val intData = dataInputStream.readInt()
val stringData = dataInputStream.readUTF()

println("Android 에서 받은 숫자 : $intData")
println("Android 에서 받은 문자열 : $stringData")

 

그리고 소켓과 서버를 차례대로 연결을 끊어주었습니다.

socket.close()
server.close()

 

 

클라이언트 코드 작성하기

안드로이드에서는 Main Thread에서 서버로부터 데이터를 받아오는 작업을 처리하면 안 되기 때문에 AsyncTask를 사용하여 코드를 작성해보겠습니다.

 

 

먼저 AndroidManifest.xml에 인터넷 사용 권한 코드를 추가해줍니다.

<uses-permission android:name="android.permission.INTERNET"/>

 

 

전체 코드는 아래와 같습니다.

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

        button.setOnClickListener {
            SocketAsyncTask().execute()
        }
    }

    inner class SocketAsyncTask : AsyncTask<Void, Void, String>() {

        override fun doInBackground(vararg params: Void?): String {
            try {

                val socket = Socket("192.168.55.131", 7777)

                val input = socket.getInputStream()
                val dataInputStream = DataInputStream(input)

                val output = socket.getOutputStream()
                val dataOutputStream = DataOutputStream(output)

                val intData = dataInputStream.readInt()
                val stringData = dataInputStream.readUTF()

                dataOutputStream.writeInt(numberEditText.text.toString().toInt())
                dataOutputStream.writeUTF(stringEditText.text.toString())

                socket.close()

                runOnUiThread {
                    serverDataTextView.text = "서버에서 받은 숫자 : $intData \n 서버에서 받은 문자열 : $stringData"
                }

            } catch (e: Exception) {
                e.printStackTrace()
            }

            return ""
        }
    }
}

 

 

socket을 열기 위해서는 해당 컴퓨터의 ip주소가 필요합니다.

 

cmd를 열고 ipconfig를 입력해줍니다.

 

 

그리고 이더넷에 있는 IPv4 값을 가져옵니다.

 

그리고 소켓을 열어주면 됩니다.

val socket = Socket("192.168.55.131", 7777)

Socket에 넣은 첫 번째 값은 ip주소이고 두 번째는 서버에서 포트를 열 때 사용한 포트 번호입니다.

 

 

val input = socket.getInputStream()
val dataInputStream = DataInputStream(input)

val output = socket.getOutputStream()
val dataOutputStream = DataOutputStream(output)

val intData = dataInputStream.readInt()
val stringData = dataInputStream.readUTF()

dataOutputStream.writeInt(numberEditText.text.toString().toInt())
dataOutputStream.writeUTF(stringEditText.text.toString())

socket.close()

runOnUiThread {
    serverDataTextView.text = "서버에서 받은 숫자 : $intData \n 서버에서 받은 문자열 : $stringData"
}

그리고 나머지 코드는 서버와 비슷합니다.

 

다른 점은 서버에서 먼저 데이터를 보냈기 때문에 데이터를 받는 코드를 먼저 작성해야 됩니다.

 

그리고 서버에서 받은 데이터를 Ui에 나타내기 위해서 runOnUiThread를 사용하여 Main Thread에서 동작하도록 하였습니다.

 

 

실행하면 아래와 같이 동작합니다.

 

 

 

 

예제 코드 : https://github.com/Im-Tae/Blog_Example/tree/master/Android/SocketExample

반응형
댓글