[์ž๋ฐ”์˜ ์ •์„] 16์žฅ ๋„คํŠธ์›Œํ‚น Networking

๋„คํŠธ์›Œํ‚น (Networking)

๋„คํŠธ์›Œํ‚น์ด๋ž€ ๋‘ ๋Œ€ ์ด์ƒ์˜ ์ปดํ“จํ„ฐ๋ฅผ ์ผ€์ด๋ธ”๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ๋„คํŠธ์›Œํฌ(network)๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค.

์ž๋ฐ”์—์„œ ์ œ๊ณตํ•˜๋Š” java.netํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋„คํŠธ์›Œํฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฐ์ดํ„ฐ ํ†ต์‹  ๋ถ€๋ถ„์„ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

ํด๋ผ์ด์–ธํŠธ(client)์™€ ์„œ๋ฒ„(server)

ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋Š” ์ปดํ“จํ„ฐ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ์—ญํ• ๋กœ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฐœ๋…์ด๋‹ค.

  • ์„œ๋ฒ„ (server) : ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ปดํ“จํ„ฐ(service provider)
  • ํด๋ผ์ด์–ธํŠธ (client) : ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ปดํ“จํ„ฐ (service user)

๋„คํŠธ์›Œํฌ ๊ตฌ์„ฑ ๋ชจ๋ธ

์„œ๋ฒ„ ๊ธฐ๋ฐ˜ ๋ชจ๋ธ(server-based model)

  • ์•ˆ์ •์ ์ธ ์„œ๋น„์Šค์˜ ์ œ๊ณต์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ๊ณต์œ ๋ฐ์ดํ„ฐ์˜ ๊ด€๋ฆฌ์™€ ๋ณด์•ˆ์ด ์šฉ์ดํ•˜๋‹ค.
  • ์„œ๋ฒ„๊ตฌ์ถ•๋น„์šฉ๊ณผ ๊ด€๋ฆฌ๋น„์šฉ์ด ๋“ ๋‹ค.

P2P ๋ชจ๋ธ(peer-to-peer model)

  • ์„œ๋ฒ„ ๊ตฌ์ถ• ๋ฐ ์šด์šฉ ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ž์›์˜ ํ™œ์šฉ์„ ๊ทน๋Œ€ํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ž์›์˜ ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ต๋‹ค.
  • ๋ณด์•ˆ์ด ์ทจ์•ฝํ•˜๋‹ค.

IP ์ฃผ์†Œ (IP address)์™€ InetAddress

  • IP์ฃผ์†Œ๋Š” ์ปดํ“จํ„ฐ(ํ˜ธ์ŠคํŠธ, host)๋ฅผ ๊ตฌ๋ณ„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ณ ์œ ํ•œ ๊ฐ’์ด๋‹ค.
  • ์ธํ„ฐ๋„ท์— ์—ฐ๊ฒฐ๋œ ๋ชจ๋“  ์ปดํ“จํ„ฐ๋Š” IP์ฃผ์†Œ๋ฅผ ๊ฐ–๋Š”๋‹ค
  • IP์ฃผ์†Œ๋Š” 4byte(32bit)์˜ ์ •์ˆ˜๊ฐ€ ๋งˆ์นจํ‘œ๋ฅผ ๊ตฌ๋ถ„์ž๋กœ โ€˜a.b.c.dโ€™ ์™€ ๊ฐ™์€ ํ˜•์‹์œผ๋กœ ํ‘œํ˜„๋œ๋‹ค.

InetAddress๋Š” ์ž๋ฐ”์—์„œ IP์ฃผ์†Œ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์–ด์กŒ๋‹ค.

1

URL(Uniform Resource Locator)

3

URI(Uniform Resource Identifier)는 인터넷에 있는 접근가능한 자원을 나타내는 유일한 주소를 일관되게 표현하는 양식을 일컫는다. URI의 하위 개념으로는 URL과 URN이 있다.

URL์€ ์ธํ„ฐ๋„ท์— ์กด์žฌํ•˜๋Š” ์—ฌ๋Ÿฌ ์„œ๋ฒ„๋“ค์ด ์ œ๊ณตํ•˜๋Š” ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์†Œ๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์œผ๋กœ โ€˜ํ”„๋กœํ† ์ฝœ://ํ˜ธ์ŠคํŠธ๋ช…: ํฌํŠธ๋ฒˆํ˜ธ/๊ฒฝ๋กœ๋ช…/ํŒŒ์ผ๋ช…?์ฟผ๋ฆฌ์ŠคํŠธ๋ง#์ฐธ์กฐโ€™์˜ ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค.

2

ํ”„๋กœํ† ์ฝœ : ์ž์›์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ทœ์•ฝ(http)
ํ˜ธ์ŠคํŠธ๋ช…(DomainName) : ์ž์›์„ ์ œ๊ณตํ•˜๋Š” ์„œ๋ฒ„์˜ ์ด๋ฆ„
ํฌํŠธ๋ฒˆํ˜ธ : ํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š” ์„œ๋ฒ„์˜ ํฌํŠธ๋ฒˆํ˜ธ
๊ฒฝ๋กœ๋ช…(path) : ์ ‘๊ทผํ•˜๋ ค๋Š” ์ž์›์ด ์ €์žฅ๋œ ์„œ๋ฒ„์˜ ์œ„์น˜
์ฟผ๋ฆฌ : URL์—์„œ ? ์ดํ›„์˜ ๋ถ€๋ถ„
์ฐธ์กฐ : URL์—์„œ #์ดํ›„์˜ ๋ถ€๋ถ„

URL ๊ฐ™์€ ๊ฒฝ์šฐ ์ž์ฃผ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ๊ณต์‹๋ฌธ์„œ์—์„œ ์ฐพ์•„ ์“ฐ๋„๋ก ํ•˜์ž.

URL Connection

URLConnection์€ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ URL๊ฐ„์˜ ํ†ต์‹  ์—ฐ๊ฒฐ์„ ๋‚˜ํƒ€๋‚ด๋Š” ํด๋ž˜์Šค์˜ ์ตœ์ƒ์œ„ ํด๋ž˜์Šค๋กœ ์ถ”์ƒํด๋ž˜์Šค์ด๋‹ค.

  • ์ƒ์† ๋ฐ›์•„ ๊ตฌํ˜„ํ•œ ํด๋ž˜์Šค๋กœ HttpURLConnection๊ณผ JarURLConnection์ด ์žˆ๋‹ค.

URL Connection์„ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น URL์˜ HeaderField, URL, ContentLength๋“ฑ ๋‹ค์–‘ํ•œ ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ URL์˜ ์—ฐ๊ฒฐํ•˜์—ฌ ํ•ด๋‹น ์ •๋ณด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

ํ•œ๋ฒˆ์— openStream์„ ํ˜ธ์ถœํ•œ ๊ฒƒ์€ URLConnection์„ ์–ป์€๋’ค getInputStream์„ ํ•œ๊ฒƒ ๊ณผ ๊ฐ™๋‹ค.

URL url = "https://www.naver.com";
InputStream in = url.openStream();
/// ์œ„๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.
URLConnection conn = url.openConnection();
InputStream in = conn.getInputStream();

์†Œ์ผ“ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์†Œ์ผ“(socket)์ด๋ž€ ํ”„๋กœ์„ธ์Šค ๊ฐ„์˜ ํ†ต์‹ ์— ์‚ฌ์šฉ๋˜๋Š” ์–‘์ชฝ ๋๋‹จ(endpoint)์„ ์˜๋ฏธํ•œ๋‹ค. ํ”„๋กœ์„ธ์Šค๊ฐ„์˜ ํ†ต์‹ ์„ ์œ„ํ•ด์„œ๋Š” ์†Œ์ผ“์ด ํ•„์š”ํ•˜๋‹ค.

TCP ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

TCP์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์„œ๋ฒ„์™€ ํด๋ผ์ด์–ธํŠธ์˜ ํ†ต์‹ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ์„œ๋ฒ„์†Œ์ผ“์„ ์‚ฌ์šฉํ•ด์„œ ์„œ๋ฒ„ ์ปดํ“จํ„ฐ์˜ ํŠน์ • ํฌํŠธ์—์„œ ํด๋ผ์ด์–ธํŠธ์˜ ์—ฐ๊ฒฐ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ค€๋น„๋ฅผ ํ•œ๋‹ค.
  2. ํด๋ผ์ด์–ธํŠธ ํ”„๋กœ๊ทธ๋žจ์€ ์ ‘์†ํ•  ์„œ๋ฒ„์˜ IP์ฃผ์†Œ์™€ ํฌํŠธ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์†Œ์ผ“์„ ์ƒ์„ฑํ•ด์„œ ์„œ๋ฒ„์— ์—ฐ๊ฒฐ์„ ์š”์ฒญํ•œ๋‹ค.
  3. ์„œ๋ฒ„ ์†Œ์ผ“์€ ํด๋ผ์ด์–ธํŠธ์˜ ์—ฐ๊ฒฐ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด ์„œ๋ฒ„์— ์ƒˆ๋กœ์šด ์†Œ์ผ“์„ ์ƒ์„ฑํ•ด์„œ ํด๋ผ์ด์–ธํŠธ์˜ ์†Œ์ผ“๊ณผ ์—ฐ๊ฒฐ๋˜๋„๋ก ํ•œ๋‹ค.
  4. ์ดํ›„ ํด๋ผ์ด์–ธํŠธ์˜ ์†Œ์ผ“๊ณผ ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ์„œ๋ฒ„์˜ ์†Œ์ผ“์€ ์„œ๋ฒ„ ์†Œ์ผ“๊ณผ ๊ด€๊ณ„์—†์ด ์ผ๋Œ€์ผ ํ†ต์‹ ์„ ํ•œ๋‹ค.

๋‹ค์‹œํ•œ๋ฒˆ ๋งํ•˜๋ฉด

  • ์„œ๋ฒ„์†Œ์ผ“(ServerSocket)์€ ํฌํŠธ์™€ ๊ฒฐํ•ฉ(bind)๋˜์–ด ํฌํŠธ๋ฅผ ํ†ตํ•ด ์›๊ฒฉ ์‚ฌ์šฉ์ž์˜ ์—ฐ๊ฒฐ์š”์ฒญ์„ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
  • ์—ฐ๊ฒฐ์š”์ฒญ์ด ์˜ค๋ฉด ์ƒˆ๋กœ์šด ์†Œ์ผ“์„ ์ƒ์„ฑํ•˜์—ฌ ์ƒ๋Œ€ํŽธ ์†Œ์ผ“๊ณผ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์—ฐ๊ฒฐํ•œ๋‹ค.

๊ฐ ์†Œ์ผ“์€ ๋‘ ๊ฐœ์˜ ์ŠคํŠธ๋ฆผ ์ฆ‰ ์ž…๋ ฅ์ŠคํŠธ๋ฆผ๊ณผ ์ถœ๋ ฅ์ŠคํŠธ๋ฆผ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ, ์ด ์ŠคํŠธ๋ฆผ๋“ค์€ ์—ฐ๊ฒฐ๋œ ์ƒ๋Œ€ํŽธ ์†Œ์ผ“์˜ ์ŠคํŠธ๋ฆผ๊ณผ ๊ต์ฐจ์—ฐ๊ฒฐ๋œ๋‹ค.

  • (์„œ๋ฒ„์†Œ์ผ“์˜ ์ž…๋ ฅ์ŠคํŠธ๋ฆผ <-> ํด๋ผ์ด์–ธํŠธ ์†Œ์ผ“์˜ ์ถœ๋ ฅ์ŠคํŠธ๋ฆผ)
  • (์„œ๋ฒ„์†Œ์ผ“์˜ ์ถœ๋ ฅ์ŠคํŠธ๋ฆผ <-> ํด๋ผ์ด์–ธํŠธ ์†Œ์ผ“์˜ ์ž…๋ ฅ์ŠคํŠธ๋ฆผ)

TCP์†Œ์ผ“ ์ฑ„ํŒ…๋ฐฉ ์˜ˆ์ œ

์ฑ„ํŒ…๋ฐฉ ์˜ˆ์ œ ๊ฐ™์€ ๊ฒฝ์šฐ ์„œ๋ฒ„์˜ ์ ‘์†ํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ์˜ ์ˆ˜๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์“ฐ๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์„ ๋ณ‘๋ ฌ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ์„œ๋ฒ„๊ฐ€ ์ ‘์†์„ ์š”์ฒญํ•œ ์ˆœ์„œ๋Œ€๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋Šฆ๊ฒŒ ์ ‘์†์„ ์š”์ฒญํ•œ ํด๋ผ์ด์–ธํŠธ๋Š” ์˜ค๋žœ ์‹œ๊ฐ„์„ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์žˆ๋‹ค.

์„œ๋ฒ„

package Network;

import java.net.*;
import java.io.*;
import java.util.*;

public class TcpIpMultichatServer {
    // ์„œ๋ฒ„์—์„œ ๋“ค์–ด์˜ค๋Š” client๋“ค์„ Thread๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ํ•ด๋‹น ์ •๋ณด๋ฅผ ๋„ฃ์–ด ๋ณด๊ด€ํ•  ๋งต
    HashMap clients;


    TcpIpMultichatServer(){
        clients = new HashMap();
        Collections.synchronizedMap(clients);
    }

    public void start(){
        ServerSocket serverSocket = null;
        Socket socket = null;

        try{
            //7777๋ฒˆ ํฌํŠธ์— ์„œ๋ฒ„ ์†Œ์ผ“์„ ์—ฐ๋‹ค.
            serverSocket = new ServerSocket(7777);
            System.out.println("์„œ๋ฒ„๊ฐ€ ์‹œ์ž‘๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");

            while(true){
                // serverSocket์— ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋ฉด ํ•ด๋‹น ์†Œ์ผ“์˜ ์—ฐ๊ฒฐ์„ ํ—ˆ์šฉํ•ด์ค€๋‹ค.
                socket = serverSocket.accept();
                System.out.println("["+socket.getInetAddress()+":"+socket.getPort()+"]์—์„œ์ ‘์†ํ•˜์˜€์Šต๋‹ˆ๋‹ค.");
                // Thread๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋“ค์–ด์˜จ ์†Œ์ผ“๊ณผ 1:1 ์—ฐ๊ฒฐ์„ ํ•˜๋Š” ์†Œ์ผ“์„ ๋งŒ๋“ค์–ด์ค„ ์˜ˆ์ •์ด๋‹ค.
                ServerReceiver thread = new ServerReceiver(socket);
                thread.start();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // HashMap์— ์ €์žฅํ•œ ๋ชจ๋“  clients๋“ค์—๊ฒŒ ์ผ๊ด„์ ์œผ๋กœ message๋ฅผ ๋ณด๋‚ด์ฃผ๋Š” ํ•จ์ˆ˜
    void sendToAll(String msg){
        Iterator it = clients.keySet().iterator();

        while(it.hasNext()){
            try{
                DataOutputStream out = (DataOutputStream)clients.get(it.next());
                out.writeUTF(msg);
            } catch (IOException e){}
        }
    }
    // ์ฑ„ํŒ… ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๋Š” mainํ•จ์ˆ˜
    public static void main(String[] args){
        new TcpIpMultichatServer();
    }

    // Client์˜ socket๊ณผ ์—ฐ๊ฒฐํ•˜๋Š” Thread
    class ServerReceiver extends Thread{
        Socket socket; // ํด๋ผ์ด์–ธํŠธ์™€ ์—ฐ๊ฒฐํ•  ์†Œ์ผ“
        DataInputStream in;
        DataOutputStream out;

        // ์„œ๋ฒ„ ์†Œ์ผ“์ด ์ƒ์„ฑํ•œ ์“ฐ๋ ˆ๋“œ์˜ input, outputStream ์„ ์ƒ์„ฑํ•ด์ฃผ๋Š” ์ƒ์„ฑ์ž
        ServerReceiver(Socket socket){
            this.socket = socket;
            try{
                in = new DataInputStream(socket.getInputStream());
                out = new DataOutputStream(socket.getOutputStream());
            } catch (IOException e){}
        }
        // ์“ฐ๋ ˆ๋“œ์˜ ๋™์ž‘
        public void run(){
            String name= "";

            try{
                // readUTFํ•จ์ˆ˜๋Š” ์Šค์ผ€๋„ˆ์ฒ˜๋Ÿผ ์ƒ๋Œ€๊ฐ€ ์ž…๋ ฅํ•˜์ง€ ์•Š์œผ๋ฉด ๊ณ„์† ๊ธฐ๋‹ค๋ฆฐ๋‹ค.
                // ์šฐ๋ฆฌ ์ฑ„ํŒ…์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ๋Š” ์—ฐ๊ฒฐ ์‹œ ๋จผ์ € ์ž๊ธฐ ์ด๋ฆ„์„ ๋ณด๋‚ด๋ฏ€๋กœ, ๋ฐ›์€ ์ด๋ฆ„์„ ์ €์žฅ
                name = in.readUTF();
                // ์ƒˆ๋กœ์šด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ ‘์†ํ–ˆ์Œ์„ ์•Œ๋ฆฐ๋‹ค.
                sendToAll("#"+name+"๋‹˜์ด๋“ค์–ด์˜ค์…จ์Šต๋‹ˆ๋‹ค.");

                // clients Map์— ์ƒˆ๋กœ์˜จ ํด๋ผ์ด์–ธํŠธ์˜ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋ฉฐ, outputStream๋„ ๊ฐ™์ด ์ €์žฅํ•œ๋‹ค.
                clients.put(name, out);
                System.out.println("ํ˜„์žฌ ์„œ๋ฒ„์ ‘์†์ž ์ˆ˜๋Š” " + clients.size() + "์ž…๋‹ˆ๋‹ค.");
                while(in != null){
                    // ์ดํ›„ client์˜ ์ •๋ณด๊ฐ€ ๋“ค์–ด์˜ฌ ๋•Œ๋งˆ๋‹ค ๊ณ„์† ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ์ฑ„ํŒ…๋ฐฉ์— ๋ฟŒ๋ ค์ค€๋‹ค.
                    // ์ŠคํŠธ๋ฆผ์ด ๋‹ซํžˆ๋ฉด in==null์ด ๋œ๋‹ค.
                    sendToAll(in.readUTF());
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // ์—ฐ๊ฒฐ์ด ๋Š๊ธฐ๋ฉด ํ•ด๋‹น ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋‚˜๊ฐ„๊ฒƒ์„ ์•Œ๋ ค์ค€๋‹ค.
                sendToAll("#"+ name + "๋‹˜์ด ๋‚˜๊ฐ€์…จ์Šต๋‹ˆ๋‹ค.");
                clients.remove(name);
                System.out.println(" ํ•ด๋‹น ์œ ์ €๋Š” ์ ‘์†์„ ์ข…๋ฃŒํ•˜์˜€์Šต๋‹ˆ๋‹ค.");
            }
        }

    }
}

ํด๋ผ์ด์–ธํŠธ

package Network;

import java.net.*;
import java.io.*;
import java.util.Scanner;

public class TcpIpMultichatClient {

    public static void main(String[] args){
        if(args.length != 1){
            System.out.println("USAGE: java TcpIpMultichatClient ๋Œ€ํ™”๋ช…");
        }
        try{
            String serverIp = "127.0.0.1";
            // serverIp์˜ 7777๋ฒˆ ํฌํŠธ๋กœ ใ…‡๋…€๊ฒฐํ•œ๋‹ค.
            Socket socket = new Socket(serverIp, 7777);
            System.out.println("์„œ๋ฒ„์— ์—ฐ๊ฒฐ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");

            // sender์™€ receiver ์“ฐ๋ ˆ๋“œ๋ฅผ ๊ฐ๊ฐ ์ƒ์„ฑํ•˜๋ฉฐ, ์—ฐ๊ฒฐ๋œ ์†Œ์ผ“์œผ๋กœ ์ŠคํŠธ๋ฆผ์„ ์—ฐ๊ฒฐํ•œ๋‹ค.
            Thread sender = new Thread(new ClientSender(socket, args[0]));
            Thread receiver = new Thread(new ClientReceiver(socket));

            sender.start();
            receiver.start();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // Sender, outputStream
    static class ClientSender extends Thread{
        Socket socket;
        DataOutputStream out;
        String name;

        ClientSender(Socket socket, String name){
            this.socket = socket;
            try{
                out = new DataOutputStream(socket.getOutputStream());
                this.name = name;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public void run(){
            Scanner scanner = new Scanner(System.in);
            try{
                // ์—ฐ๊ฒฐ์ด ๋˜๋ฉด ๋จผ์ € ์ด๋ฆ„๋ถ€ํ„ฐ ๋ณด๋‚ด์ค€๋‹ค.
                if(out!=null){
                    out.writeUTF(name);
                }
                // ์—ฐ๊ฒฐ์ด ๋Š๊ธฐ๊ธฐ ์ „๊นŒ์ง€ Scanner์—์„œ ์ž…๋ ฅ๋œ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋“ค์„ ๋‹ค์‹œ ๋ณด๋‚ด์ค€๋‹ค.
                while(out!=null) out.writeUTF("[" + name + "]" + scanner.nextLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    // Reciever, inputStream
    static class ClientReceiver extends Thread{
        Socket socket;
        DataInputStream in;

        ClientReceiver(Socket socket){
            this.socket = socket;
            try{
                in = new DataInputStream(socket.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public void run(){
            // ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋“ค์„ ๋ฐ”๋กœ ์ถœ๋ ฅํ•ด์ค€๋‹ค.
            while(in != null){
                try{
                    System.out.println(in.readUTF());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

UDP ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

  • UDP์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์†Œ์ผ“์€ DatagramSocket์ด๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ DatagramPacket์— ๋‹ด์•„์„œ ์ „์†กํ•œ๋‹ค.
  • UDP๋Š” ์—ฐ๊ฒฐ์ง€ํ–ฅ์ ์ธ ํ”„๋กœํ† ์ฝœ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ServerSocket์ด ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.
  • DatagramPacket์€ ํ—ค๋”์™€ ๋ฐ์ดํ„ฐ๋กœ ๊ตฌ์„ฑ๋˜์–ด์žˆ๋‹ค.

    • ํ—ค๋”์—๋Š” DatagramPacket์„ ์ˆ˜์‹ ํ•  ํ˜ธ์ŠคํŠธ์˜ ์ •๋ณด(์ฃผ์†Œ์™€ ํฌํŠธ)๊ฐ€ ์ €์žฅ๋˜์–ด์žˆ๋‹ค.

UDP ์†Œ์ผ“ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์˜ˆ์ œ

์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์„œ๋ฒ„์‹œ๊ฐ„์„ ์ „์†ก๋ฐ›์•„ ์ถœ๋ ฅํ•˜๋Š” UDP ์†Œ์ผ“ ํด๋ผ์ด์–ธํŠธ, ์„œ๋ฒ„ ํ”„๋กœ๊ทธ๋žจ ์˜ˆ์ œ์ด๋‹ค.

  • ํด๋ผ์ด์–ธํŠธ๊ฐ€ DatagramPacket์„ ํ†ตํ•ด DatagramSocket์œผ๋กœ ์„œ๋ฒ„์— ์ „์†กํ•˜๋ฉด, ์„œ๋ฒ„๋Š” ์ „์†ก๋ฐ›์€ DatagramPacket์˜ getAddress(), getPort()๋ฅผ ํ˜ธ์ถœํ•ด์„œ ํด๋ผ์ด์–ธํŠธ์˜ ์ •๋ณด๋ฅผ ์–ป์–ด์„œ ์„œ๋ฒ„ ์‹œ๊ฐ„์„ Datagrampacket์— ๋‹ด์•„์„œ ์ „์†กํ•œ๋‹ค.

Server

package Network;

import java.net.*;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.text.SimpleDateFormat;

public class UdpServer {
    public void start() throws IOException{
        // ํฌํŠธ 7777๋ฒˆ์„ ์‚ฌ์šฉํ•˜๋Š” ์†Œ์ผ“์„ ์ƒ์„ฑํ•œ๋‹ค
        DatagramSocket socket = new DatagramSocket(7777);
        DatagramPacket inPacket, outPacket;

        byte[] inMsg = new byte[100];
        byte[] outMsg;

        while(true){
            //๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ธฐ ์œ„ํ•œ ํŒจํ‚ท์„ ์ƒ์„ฑํ•œ๋‹ค.
            inPacket = new DatagramPacket(inMsg, inMsg.length);

            // ํŒจํ‚ท์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ (receive)ํ•œ๋‹ค.
            socket.receive(inPacket);

            //์ˆ˜์‹ ํ•œ ํŒจํ‚ท์œผ๋กœ๋ถ€ํ„ฐ client์˜ IP์ฃผ์†Œ์™€ Port๋ฅผ ์–ป๋Š”๋‹ค.
            InetAddress address = inPacket.getAddress();
            int port = inPacket.getPort();

            // ์„œ๋ฒ„์˜ ํ˜„์žฌ ์‹œ๊ฐ„์„ ์‹œ๋ถ„์ดˆ ํ˜•ํƒœ [hh:mm:ss] ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค
            SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
            String time = sdf.format(new Date());
            outMsg = time.getBytes(); //time์„ byte๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜

            // ํŒจํ‚ท์„ ์ƒ์„ฑํ•ด์„œ Client์—๊ฒŒ ์ „์†ก(send)ํ•œ๋‹ค.
            outPacket = new DatagramPacket(outMsg, outMsg.length, address, port);
            socket.send(outPacket);
        }
    }

    public static void main(String[] args){
        try{
            new UdpServer().start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Client

package Network;

import java.net.*;
import java.io.*;
public class UdpClient {
    public void start() throws IOException, UnknownHostException{
        DatagramSocket datagramSocket = new DatagramSocket();
        InetAddress serverAddress = InetAddress.getByName("127.0.0.1");

        // ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋  ๊ณต๊ฐ„์œผ๋กœ byte๋ฐฐ์—ด์„ ์ƒ์„ฑํ•œ๋‹ค.
        byte[] msg = new byte[100];

        DatagramPacket outPacket = new DatagramPacket(msg, 1, serverAddress, 7777);
        DatagramPacket inPacket = new DatagramPacket(msg, msg.length);

        datagramSocket.send(outPacket);
        datagramSocket.receive(inPacket);

        System.out.println("current server time : " + new String(inPacket.getData()));

        datagramSocket.close();
    }
    public static void main(String[] args){
        try{
            new UdpClient().start();
        }  catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Reference


Written by@Gomster
ํ•ญ์ƒ ๋…ธ๋ ฅํ•˜๊ณ  ๋‚˜์•„๊ฐ€๋Š” ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ณ  ์‹ถ์€ ๋Œ€ํ•™์ƒ์ž…๋‹ˆ๋‹ค.

GitHub