Java(Android Studio)에서 소켓 통신하기

Jinhee Kim·2022년 12월 5일
0

해당 포스트에서는 소켓의 개념보다 실제 구현을 위주로 설명하겠습니다.

  1. AndroidManifest.xml 에 권한을 추가합니다.
<uses-permission android:name="android.permission.INTERNET"/>
  1. activity_main.xml 에 전송 버튼과 결과를 표시할 textView를 생성합니다.
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="@android:color/holo_blue_bright"
        android:orientation="vertical">

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="전송" />

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >

                <TextView
                    android:id="@+id/textView"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textSize="20sp" />
            </LinearLayout>
        </ScrollView>
    </LinearLayout>
  1. MainActivity.java 에 소켓 관련 동작을 작성합니다.
	TextView textView;
    Handler handler = new Handler();

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

		// 결과를 표시할 텍스트뷰
        textView = findViewById(R.id.textView);

		// 전송 버튼 선언
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // final String data = editText.getText().toString();

                // 스레드 내부에서 send 메서드 호출
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        send();
                    }
                }).start();

            }
        });
    }

    // 클라이언트에서 데이터 전송
    public void send() {
        // 소켓을 선언한다.
        try (Socket client = new Socket()) {
            // 소켓에 접속하기 위한 접속 정보를 선언한다.
            InetSocketAddress ipep = new InetSocketAddress("ip address", port number);
            // 소켓 접속!
            client.connect(ipep);
            // 소켓이 접속이 완료되면 inputstream과 outputstream을 받는다.
            try (OutputStream sender = client.getOutputStream();
            	InputStream receiver = client.getInputStream();) {

                // 전송할 메시지를 작성한다.
                String msg = "java test message - Hello";

                // string을 byte배열 형식으로 변환한다.
                byte[] data = msg.getBytes();
                // ByteBuffer를 통해 데이터 길이를 byte형식으로 변환한다.
                ByteBuffer b = ByteBuffer.allocate(4);

                // byte포멧은 little 엔디언이다.
                b.order(ByteOrder.LITTLE_ENDIAN);
                b.putInt(data.length);

                // 데이터 길이 전송
                sender.write(b.array(), 0, 4);
                // 데이터 전송
                sender.write(data);
                printClientLog("데이터 전송함.");

                data = new byte[4];
                // 데이터 길이를 받는다.
                receiver.read(data, 0, 4);

                // ByteBuffer를 통해 little 엔디언 형식으로 데이터 길이를 구한다.
                b = ByteBuffer.wrap(data);
                b.order(ByteOrder.LITTLE_ENDIAN);
                int length = b.getInt();

                // 데이터를 받을 버퍼를 선언한다.
                data = new byte[length];
                // 데이터를 받는다.
                receiver.read(data, 0, length);

                // byte형식의 데이터를 string형식으로 변환한다.
                msg = new String(data, "UTF-8");

                // 텍스트뷰에 출력한다.
                printClientLog("서버로부터 받음 : " + msg);

                // 콘솔에 출력한다.
                System.out.println(msg);
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }


    // 텍스트뷰에 글자 출력
    public void printClientLog(final String data) {
        Log.d("MainActivity", data);

        // 새로 만들어진 스레드에서 호출되는 메서드이므로, 핸들러 객체 이용
        handler.post(new Runnable() {
            @Override
            public void run() {
                textView.append(data + "\n");
            }
        });

    });
    }

서버 부분은 별도의 구현이 필요합니다.
테스트 동작 결과, python 등 다른 언어와의 통신도 수행 가능합니다. :-)

profile
컴퓨터공학과 학부생

0개의 댓글