아쿠의 개발 일지

[Socket] 소켓 통신의 기본 본문

Programming/Java

[Socket] 소켓 통신의 기본

디아쿠 2024. 6. 6. 14:58

소켓 통신은 컴퓨터 네트워크 상에서 서로 다른 두 응용 프로그램이 데이터를 주고 받기 위해 사용하는 통신 방식이다.

소켓은 네트워크 연결을 위한 엔드 포인트를 의미하며, 소켓 통신은 주로 클라이언트- 서버 모델에서 사용 된다.

 

클라이언트는 서버에 연결을 요청 -> 서비스 이용

서버는 클라이언트의 요청을 받아들이고 -> 응답을 제공

 

아래 코드는 네트워크 소켓을 이용하여, 클라이언트 애플리케이션을 구현한 것이다.

클라이언트는 서버에 연결하여 데이터를 주고 받을 수 있다.

 

import java.io.*;
import java.net.Socket;

public class Client {
    public static void main(String[] args) {
        Socket clientSocket;

        try {
            clientSocket = new Socket("192.168.0.103", 80);

            ReadThread readThread = new ReadThread(clientSocket);
            WriteThread writeThread = new WriteThread(clientSocket);
            readThread.start();
            writeThread.start();

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

 

  1. client 라는 공용 클래스 선언
  2. 소켓 생성 및 서버 연결 ( ip주소와 포트번호에 연결을 시도하도록 )
  3. ReadThread와 WriteThread 객체를 생성하고 clientSocket을 인자로 전달 받는다

여기에서 ReadThread를 먼저 보면,

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class ReadThread extends Thread{
    Socket socket;
    InputStream inputStream;
    InputStreamReader reader;
    BufferedReader br;

    public ReadThread(Socket socket) throws IOException {
        this.socket = socket;
        this.inputStream = this.socket.getInputStream();
        this.reader = new InputStreamReader(inputStream, "UTF-8");
        this.br = new BufferedReader(reader);
    }

    @Override
    public void run() {
        String result;
        while(true){
            try {
                result = br.readLine();
                System.out.println();
                System.out.println("받은 메시지 : " + result);

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

 

inputStream을 통해서 바이트 단위의 입력을 읽을 수 있도록 한다.

InputStreamReader는 바이트 스트림을 문자 스트림으로 변환 해 주는 클래스이다.

BufferedReader는 문자 입력 스트림을 버퍼링하여 효율적으로 읽을 수 있도록 해준다.

여기에서 readLine() 메소드를 사용하여 라인 단위로 입력을 읽을 수 있다.

 

result에 readLine으로 한 줄씩 읽은 라인을 저장하고 이를 다 출력 할 때까지 while문 안에 무한 반복을 돌린다.

 

이렇게 읽어오는 작업을 하는 ReadThread와

쓰는 작업을 하는 WriteThread를 구분지었다.

 

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class WriteThread extends Thread{
    Socket socket;
    OutputStream outputStream;
    PrintStream printStream;

    public WriteThread(Socket socket) throws IOException {
        this.socket = socket;
        this.outputStream = socket.getOutputStream();
        this.printStream = new PrintStream(outputStream);
    }

    @Override
    public void run() {
        String message;
        Scanner sc;
        sc = new Scanner(System.in);

        while(true){
            try {
                System.out.print("메시지 입력 : ");
                message = sc.nextLine();
                printStream.println(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

 

전달된 소켓 객체를 현재 클래스의 socket 변수에 할당한다.

outputStream은 소켓을 통해 데이터를 바이트 단위로 전송하는 데 사용된다.

서버로 데이터를 보낸다고 생각하면 된다.

 

PrintStream으로 래핑하여 편리하게 데이터를 전송할 수 있게 한다. 

데이터를 텍스트 형식으로 출력하는 데 사용된다. 

println()을 통해 텍스트 데이터를 쉽게 전송할 수 있다. 

 

스레드를 실행하기 위해 run() 메소드를 사용한다.

메세지를 저장하기 위해 message 변수를 생성하고,

콘솔 입력을 받기 위한 Scanner 객체를 생성한다.

Sanner 객체를 system.in 입력 스트림과 연결한다.

 

무한 루프 while문을 사용하여, 메세지를 입력하는 창을 출력 시키고

사용자가 입력한 메세지를 읽어온다.

printStream을 통해 메세지를 소켓을 통해 서버로 전송한다.

 

Socket clientSocket = serverSocket.accept();

 

서버에서는 클라이언트가 접속을 보내면 accept를 사용하여 연결을 허용해준다.

 

A Long Life 블로그 참고

728x90

'Programming > Java' 카테고리의 다른 글

[SpringBoot] Entity간의 관계 설정  (3) 2024.06.23
[SpringBoot] RestController  (0) 2024.06.23
[Method] method overloading 기본(2)  (0) 2024.06.22
[Method] method Overloading 기본  (0) 2024.06.22
[Thread] Thread 기본  (0) 2024.06.02