[Java] TCP/UDP server, client 구현

HodooHa·2024년 5월 2일
post-thumbnail

[계층적 구조의 TCP/IP]

애플리케이션으로부터 전달받은 데이터는 TCP 계층을 거쳐 IP 계층으로 전달되는데, TCP 계층은 TCP(Transmission Control Protocol)UDP(User Datagram Protocol)로 구분할 수 있다.
신뢰성이 요구되는 애플리케이션에서는 TCP를 사용하고, 간단한 데이터를 빠른 속도로 전송하는 애플리케이션에서는 UDP를 사용한다.


[TCP를 이용한 통신]


송신측과 수신측의 연결이 이루어진 것을 확인한 다음에 데이터의 전송이 이루어진다.
데이터가 제대로 전송이 되면 수신측으로부터 응답을 받게 되는데, 응답을 받지 못하면 데이터를 재전송한다.


[UDT를 이용한 통신]

반면 UDP는 송신측과 수신측이 연결을 거치지 않고 일방적인 데이터 전송만 있으며 수신측으로부터 응답은 따로 받지 않는다.

[출처] 네이버 지식백과, https://terms.naver.com/entry.naver?docId=2270477&cid=51173&categoryId=51173


TCP와 UDT를 각각 이용하여 간단한 server와 client를 구현해보았다.

[TCP 이용 예시]

[TCPServer클래스]

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
    public static void main(String[] args) throws IOException {
        // 1. 서버의 포트를 정함 (0~65535까지 가능 -> 보통 0~1023는 사용됨) 8000~9000으로 설정하자. port가 중복되면 에러가 됨. 
        ServerSocket server = new ServerSocket(9200);

        System.out.println("클라이언트의 요청을 기다리는 중");

        int count = 0;

        while (true) {
            //
            // 2. 클라이언트에서 접속 요청이 오면 요청을 수락한 후 클라이언트에 대한 소켓 생성
            Socket socket = server.accept();
            count++;
            System.out.println("클라이언트 연결됨 > " + count + " 접속 ");
            
            // 3. 연결된 클라이언트와 스트림 생성
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            out.print("java programmer");

            // 4. 소켓 닫기
            out.close();
            socket.close();
        }
    }
}

[TCPClient클래스]

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

public class TCPClient {

    public static void main(String[] args) throws IOException {
        // 1. 클라이언트 입장에서는 서버의 ip, port를 알아야 함.
        for (int i = 0; i < 100; i++) {

            // 2. 서버의 ip주소와 포트를 매개 변수로 하여 클라이언트용 소켓 객체 생성
            Socket socket = new Socket("localhost", 9200);

            // 3. 서버와 통신할 스트림 오픈
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
         
            String data = bufferedReader.readLine();
            System.out.println("서버에서 받은 데이터 " + data);
        }
    }
}

[UDP 이용 예시]

[UDPSender클래스]

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class UCPSender {

    public static void main(String[] args) throws Exception {

        // 소켓 생성
        DatagramSocket socket = new DatagramSocket();

        // 패킷에 ip와 포트를 넘겨줘야 하므로 ip를 변수에 담기
        InetAddress ip = InetAddress.getByName("127.0.0.1");

        // 보낼 메세지
        String str = "java programmer haha";

        // 바이트로 변환해서 바이트 배열로 담기
        byte[] data = str.getBytes();

        // 패킷 생성, 데이터, 길이, ip, port로 생성
        DatagramPacket packet = new DatagramPacket(data, data.length, ip, 9300);

        // socket을 사용해서 packet을 전달
        socket.send(packet);

        // 소켓 닫기
        socket.close();
    }
}

[UDPReceiver클래스]

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class UDPReceiver {
    public static void main(String[] args) throws IOException {

        // udp 소켓 생성
        DatagramSocket socket = new DatagramSocket(9300);

        // 바이트 배열로 받기 위한 공간 할당
        byte[] data = new byte[256];

        // 받을 패킷을 생성해놓고 대기
        DatagramPacket packet = new DatagramPacket(data, data.length);

        System.out.println("받을 준비중 ");

        // 패킷이 전달되면 받음
        socket.receive(packet);

        System.out.println(new String(data));

        // 소켓 닫기
        socket.close();
    }
}

본 포스팅은 멀티캠퍼스의 멀티잇 백엔드 개발(Java)의 교육을 수강하고 작성되었습니다.

profile
성장하는 개발자, 하지은입니다.

0개의 댓글