본문 바로가기
개발/Android

[Android] Socket 통신 예제

by 준그래머 2023. 12. 5.
반응형

시작

Android 앱에서 네트워크 통신을 하기 위해 Socket을 이용한 통신 방법이 있다. 이 게시물에서는 Socket 통신의 예제만 정리할 예정이며 따로 개념을 설명하진 않을 것이다. Socket 통신 예제 시나리오는 다음과 같다.

  1. 입력된 텍스트를 서버에 전송
  2. 서버에서 결과 텍스트를 받아 텍스트로 출력

 

권한 추가

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

AndroidManifest.xml에 인터넷 권한을 먼저 추가 한다.

 

 

Layout 구현

<?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"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/et_send_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:minWidth="48dp"
        android:minHeight="48dp"
        app:layout_constraintEnd_toStartOf="@+id/btn_send"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="24dp"
        android:layout_marginRight="24dp"
        android:text="Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_send_result"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginTop="24dp"
        android:layout_marginEnd="24dp"
        android:layout_marginRight="24dp"
        android:text="보낸 메시지 :"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_send_input" />

    <TextView
        android:id="@+id/tv_receive_result"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="24dp"
        android:layout_marginLeft="24dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="24dp"
        android:layout_marginRight="24dp"
        android:text="받은 메시지 :"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_send_result" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

기능 구현

버튼 클릭 시 입력된 텍스트를 서버로 전송하고 결과 텍스트를 다시 리턴 받도록 구현했다.

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "SocketTest";
    private static final String SERVER_IP = "Your Server IP";
    private static final int PORT = 9999; // 포트 번호

    private Socket client;
    private String receiveMessage = "";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnSend = findViewById(R.id.btn_send);
        EditText etSendInput = findViewById(R.id.et_send_input);
        TextView tvSendResult = findViewById(R.id.tv_send_result);
        TextView tvReceiveResult = findViewById(R.id.tv_receive_result);

        btnSend.setOnClickListener(view -> {
            final String inputMessage = String.valueOf(etSendInput.getText());
            tvSendResult.setText("보낸 메세지: " + inputMessage);
            ExecutorService executors = Executors.newSingleThreadExecutor();
            executors.submit((Callable<Void>) () -> {
                try {
                    client = new Socket(SERVER_IP, PORT);
                    DataOutputStream dataOutput = new DataOutputStream(client.getOutputStream());
                    DataInputStream dataInput = new DataInputStream(client.getInputStream());
                    dataOutput.writeUTF(inputMessage);
                    receiveMessage = dataInput.readUTF();
                } catch (UnknownHostException e) {
                    Log.e(TAG, "UnknownHostException: ", e);
                } catch (IOException e) {
                    Log.e(TAG, "IOException: ", e);
                }
                return null;
            });
            executors.shutdown();
            try {
                if(!executors.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) executors.shutdownNow();
                tvReceiveResult.setText("받은 메세지: " + receiveMessage);
            } catch (InterruptedException e) {
                e.printStackTrace();
                executors.shutdownNow();
            }
        });
    }
}

 

 

반응형