본문 바로가기

개발자

2023-01-16 소켓 통신 연습

PC1 - 공유기 - 모뎀 - KT - 위성 - LTE - 공유기 - Controller - PC2

 

 

 

Socket 인가 ?

C - 구조체 Java - Object 구조가 달라서

서로의 통신을 위해 byte 단위로 정보를 주고 받음

 

Server Client 특정 Port 통해 실시간으로 양방향 통신

 

 

 

Process :

 프로세스당 최소 1개의 스레드(메인 스레드)를 가지고 있다.

 

Stack : 지역변수 할당과 함수 호출  전달되는 인자값들을 저장하기 위한 공간(임시 메모리)

Heap : C malloc, calloc Java,C++ new 통한 동적 할당을 위해 존재하는 공간

 

 

Thread :

 프로세스(process) 내에서 실제로 작업을 수행하는 주체

할당 받은 자원을 이용하는 실행 단위

 

 

 

 

Context Switching :

현재 진행하고 있는 Task(Process, Thread)의 상태를 저장하고 다음 진행할 Task의 상태 값을 읽어 적용하는 과정

 

 

멀티 프로세스 대신 멀티 스레드를 사용하는 이유 ?

프로그램을 여러 개 키는 것보다

하나의 프로그램 안에서 여러 작업을 해결하는 것이다.

 

 

 

 

 

 

 

 

package com.example.a0116;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    EditText addressInput; //호스트 IP 입력상자
    EditText dataInput; //서버로 전송할 데이터 입력상자

    String str;
    String addr;

    String response; //서버 응답

    Handler handler = new Handler(); // 토스트를 띄우기 위한 메인스레드 핸들러 객체 생성

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

        addressInput = findViewById(R.id.addressInput);
        dataInput = findViewById(R.id.dataInput);
        Button socketConnectBtn = findViewById(R.id.socketConnectBtn);

        /*
        버튼을 클릭했을 때
        1. 입력상자의 서버 IP 주소와 전송할 데이터 가져오기
        2. 소켓통신을 위한 스레드의 매개변수로 넣어주어 스레드 객체 생성
        3. 스레드 시작
        */
        socketConnectBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addr = addressInput.getText().toString().trim();
                str = dataInput.getText().toString();
                SocketThread thread = new SocketThread(addr, str);
                thread.start();
            }
        });
    }

    class SocketThread extends Thread{

        String host; // 서버 IP
        String data; // 전송 데이터

        public SocketThread(String host, String data){
            this.host = host;
            this.data = data;
        }

        @Override
        public void run() {

            try{
                int port = 503; //포트 번호는 서버측과 똑같이
                Socket socket = new Socket(host, port); // 소켓 열어주기
                ObjectOutputStream outstream = new ObjectOutputStream(socket.getOutputStream()); //소켓의 출력 스트림 참조
                outstream.writeObject(data); // 출력 스트림에 데이터 넣기
                outstream.flush(); // 출력

                ObjectInputStream instream = new ObjectInputStream(socket.getInputStream()); // 소켓의 입력 스트림 참조
                response = (String) instream.readObject(); // 응답 가져오기
                Log.d("서버 응답",response);

                /* 토스트로 서버측 응답 결과 띄워줄 러너블 객체 생성하여 메인스레드 핸들러로 전달 */
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, "서버 응답 : " + response, Toast.LENGTH_LONG).show();
                    }
                });

                socket.close(); // 소켓 해제

            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/addressInput"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:hint="서버 IP"
        android:textSize="20dp"
        android:layout_marginTop="200dp"
        android:layout_gravity="center_horizontal"/>

    <EditText
        android:id="@+id/dataInput"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:hint="보낼 데이터"
        android:textSize="20dp"
        android:layout_marginTop="10dp"
        android:layout_gravity="center_horizontal"/>

    <Button
        android:id="@+id/socketConnectBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="서버 전송"
        android:textSize="24dp"
        android:layout_marginTop="20dp"
        android:layout_gravity="center_horizontal"/>

</LinearLayout>