Cohe

17. Network, 서버 만들기! 본문

개발 언어/JAVA

17. Network, 서버 만들기!

코헤0121 2024. 3. 28. 17:00
728x90

네트워크

network : 컴퓨터의 네트워크는 컴퓨터와 컴퓨터를 연결하는 연결망을 의미함. Internet : (협의-좁은 의미) : 네트워크와 네트워크의 연결. (광의-넓은 의미-이게 요즘의미) : 전세계적으로 네트워크를 연결하여 구성한 것을 의미함.

네트워크 모델 :

  1. OSI 7 Layer(참조) : 1]참조용, 2]교육용
    • 다양한 통신 프로토콜이 있어 다 아우를 수 있도록 만들 수 있음 호환성을 높일 수 있다.
    • [상위 계층] - 데이터를 생성
      • 7계층 Applicaiton Layer- 응용 계층
        • 네트워크 통신을 위한 원본 데이터를 생성하는 계층 ex) HTTP, DNS, FTP ...
      • 6계층 Presentation Layer- 표현 계층
        • 인코딩, 암호화, 압축 등을 처리하는 계층
      • 5계층 Session Layer- 세션계층
        • 연결(Session)을 생성하고, 유지하고, 종료하는 일련의 과정을 처리하는 계층 주소 여부에 따라서
    • [하위 계층] - 데이터를 전달
      • 4계층 Transport Layer- 전송계층
        • 서비스를 구분(port)하는 계층으로 데이터 전송 방식(tcp/udp)을 결정함. HTTP(80), DNS(53), FTP(21(control),20(data)), SSH(22), Telnet(23), HTTPS(443), DHCP(67,68) 주소 : Port(2byte 길이 -> 0 ~ 65537)
        • 0 ~ 1023 : 전통적인 서비스를 구분하는 포트
        • 1024 ~ 65537 : 임의의 포트
        • 전송프로토콜 : TCP/UDP
          • TCP : 신뢰성 높다. 흐름 제어 3way handshake 동작 : 동기화 작업 1:1 통신에서 사용!
          • UDP : 처리속도 빠르고, 흐름 제어X 1:다수 통신이 가능! -> broadcast 통신방식
      • 3계층 Network Layer- 네트워크계층 → 출발지 장비에서부터 도착지 장비까지 통신 경로를 결정하는 계층
    •  
	 주소 : IP(4byte 길이 -> 2^32)
   옥텟 단위로 표현  : 192.168.10.123  점과 점사이 비트의 갯수 8비트 (0 ~ 255)

 A  가장 큰 네트워크, 약 1600만여개의 장비를 가질 수 있는 네트워크
          범위 0.0.0.0 ~ 127.0.0.0(128개의 네트워크, 0.0.0.0 ~ 127.0.0.0)
          네트워크 표시로 사용하는 Mask : subnet mask => 255.0.0.0
          프리픽스 방식의 표현 /8

    * 사설 IP : 10.0.0.0/8  -> 내부 네트워크를 구성하기 위해서 사용하는 IP를 의미함.
    * 0.0.0.0/8 사용 X -> IP 전체를 가리키는 용도로 사용!
    * 127.0.0.0/8 사용 X -> 로컬 호스트 장비를 가리키는 주소로 사용

 B  중범위 네트워크, 약 65000여개의 장비를 가질 수 있는 네트워크
          범위 128.0.0.0 ~ 191.255.255.255
          네트워크 표시로 사용하는 Mask : subnet mask => 255.255.0.0
          프리픽스 방식으로 표현 /16

  * 사설 IP : 172.16.0.0/12 (172.16.0.0 ~ 172.31.255.255 : 16개 B클래스 네트워크)
  * 169.254.0.0/16 - DHCP 동작 중 주소를 받지 못한 경우 사용하는 내부 통신용 주소
  DHCP : 호스트(PC)에 자동으로 통신을 위한 IP주소 내역을 설정하는 프로토콜

 C  소규모 네트워크, 254개 장비를 가지를 수 있는 네트워드
    192.0.0.0 ~ 223.255.255.255
          네트워크 표시로 사용하는 Mask : subnet mask => 255.255.255.0
          프리픽 방식으로 표현 /24

    * 사설IP : 192.168.0.0/16 (192.168.0.0/24 ~ 192.168.255.0/24 : 256개 C클래스 네트워크)
    ====================== C 클래스까지 통신용 주소 ====================================
 D  멀티캐스트 통신을 위한 주소로 사용!
           멀티캐스트란? 그룹 전송을 위해서 사용하는 통신 주소를 의미함.
    224.0.0.0 ~ 239.255.255.255

 E  240.0.0.0 ~ 255.255.255.255 대역대의  E클래스는 연구 목적으로 실제로 사용 X
    • 2계층 Data-Link Layer- 데이타링크계층 : 네트워크 내의 장비들 간의 통신을 위한 계층 주소 : MAC(6byte 길이 -> 2^48) - 고정되어 있음
    • 1계층 Physical Layer- 물리계층 : 통신을 위한 선, 커넥터, 전송 비트 주소 : X
  1. TCP/IP
    • Application (7,6,5)
    • Transport (4)
    • Internet (3)
    • Network-Interface(1,2)

Socket

  • 네트워크 상에서 클라이언트와 서버가 특정 포트를 통해양방향 통신이 가능하게 만들어주는 소프트웨어 장치
  • endpoint를 소켓이라고 한다.

클라이언트와 서버의 네트워크 연결 순서

  • TCP 연결
  1. 클라이언트가 연결 요청을 한다.
  2. 서버가 연결 수락을 한다.
    3 way handshake ⇒ 연결 협상
  3. 클라이언트에서 서비스 처리 요청
  4. 서버에서 클라이언트의 요청 처리
  5. 서버에서 처리된 결과를 클라이언트에게 전달

주소 관련 클래스

  • INetAddress : checked → try-catch가 필요
  • //getByName메서드를 통해 INetAddress 객체 생성

  • URL : 인터넷 자원 접근 위치
  • 프로토콜 :// 호스트명:포트번호/경로명/경로명/파일?쿼리스트링
    • URL 인코딩 : 데이터 전송 시 아스키코드를 전송해야하기 때문에 1byte 씩 잘라서 보낸다.

 

 

서버만들기

서버 코드

 

package I_java;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.FileReader;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class I03_ServerEx {
    public static void main(String[] args) {
        //소켓 생성
        ServerSocket server =null;
        try {
            server = new ServerSocket(9999);

            //무한 반복 (클라이언트 접속 대기)
            while (true) {
                System.out.println("클라이언트 접속 대기");
                Socket client = server.accept(); //연결 성공시 Socket 객체 반환

                System.out.println("스레드 생성"); //클라이언트와 서버간의 개별 세션 생성을 위함

                //http 스레드를 만듦

                HTTPThread ht = new HTTPThread(client);
                ht.start();

            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

}

class HTTPThread extends Thread {
    private Socket client;

    BufferedReader br;
    PrintWriter pw;     //web에서 사용할 데이터 전달을 위해서 사용

    public HTTPThread(Socket client){
        this.client = client;
       
        try {
            br = new BufferedReader(new InputStreamReader(client.getInputStream())); //클라이언트가 보낸 데이터 처리를 위해 (서버 내부 처리)
            pw = new PrintWriter(client.getOutputStream()); //응답 데이터 처리 (외부로 보냄)
        } catch (IOException e) {System.out.println(e.getMessage());}


    }

    @Override
    public void run() {
        BufferedReader fbr = null;

        DataOutputStream outToClient = null;

        try {
            String line = br.readLine(); //Line : GET /filename/HTTP/1.1  http 요청 헤더의 첫번째줄
            System.out.println("Http Header : "+line); //file네임을 가져오려고 함!
            int start = line.indexOf("/")+1; //file name은 root file 이후부터
            int end = line.lastIndexOf("HTTP")-1; //http 이전까지

            String fileName = line.substring(start, end);

            //서버에 요청받은 데이터를 전달해줄 것이다.
            if(fileName.equals("")){
                fileName = "index.html";
            }
            System.out.println("사용자 요청 파일 : "+fileName);
            fbr = new BufferedReader(new FileReader(fileName));

            String fileLine = null;
            pw.println("HTTP/1.0 200 Document Follows \r\n");
            while ((fileLine = fbr.readLine())!=null) { //값을 집어넣겠다!!!
                pw.println(fileLine);
                pw.flush();
               
            }
        } catch (IOException e) {
            // TODO: handle exception
            System.out.println(e.getMessage());
        } finally{
            try {
                if(br !=null) br.close();
                if(pw !=null) pw.close();
                if(client != null) client.close();
            } catch (Exception e2) {
                System.out.println(e2.getMessage());
            }
        }
    }
   
}
  • CMD에서 해당 파일을 만들어야
    • netstat -an | findstr "9999" TCP 0.0.0.0:9999 0.0.0.0:0 LISTENING TCP [::]:9999 [::]:0 LISTENING
      • -an : all number
    • 인터넷 창에서 ip주소 + 포트번호(여기서는 9999입니다)를 추가해서 넣어줌
      • index.html 을 추가해서 넣어주자

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My First Web Page</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <p>This is a simple example of an HTML page.</p>
</body>
</html>

 

그럼 이렇게 된다!!!!

 

UDP 통신

 

서버 만들기

package I_java;

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

public class I04_UDPServer {
    public static void main(String[] args) {
        try {
            //data gram Socket 객체 생성
            DatagramSocket socket = new DatagramSocket(9500);

            DatagramPacket inPacket;
            byte[] inMsg = null;

            while (true) {
                //데이터를 받기 위한 바이트 배열 생성
                inMsg = new byte[1024];
                //DatagramPacket 객체를 생성
                inPacket = new DatagramPacket(inMsg, inMsg.length); //버퍼 공간과 버퍼의 크기를 알려주니까 그만큼 크기를 주고 받는다
                //packet 데이터 수신
                socket.receive(inPacket);
                //문자열로 저장
                String msg = new String(inMsg,0,inPacket.getLength());
                System.out.println("클라이언트 메세지 : "+msg);

                //클라이언트 IP 를 저장한다.
                InetAddress address = inPacket.getAddress();
                //클라이언트 port
                int port = inPacket.getPort();
                System.out.println("클라이언트 주소 : "+address);
                System.out.println("클라이언트 포트 번호 : "+port);
               
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }  
    }

}

cmd 확인

명령어 > netstat -an | findstr 9500

확인 > 

  UDP    0.0.0.0:9500           *:*
  UDP    [::]:9500              *:*

 

client 정리

package I_java;

import java.io.BufferedReader;
import java.net.InetAddress;
import java.io.InputStreamReader;
import java.net.DatagramSocket;
import java.net.DatagramPacket;

public class I05_UDPClient {

    public static void main(String[] args) {
        //UDP 클라이언트는 메시지 전송

        try {
            //keybord input -> read by BufferedReader

            BufferedReader sysin = new BufferedReader(new InputStreamReader(System.in));
           
            //server ip
            InetAddress serverip = InetAddress.getByName("127.0.0.1");
            while (true) {
                //one line read

                String data = sysin.readLine();
                DatagramSocket dataSocket = new DatagramSocket();
                //문자열을 바이트 배열에 저장
                byte[] msg1 = data.getBytes();

                //server transport (data, data length, server ip, port number)
                DatagramPacket outpacket = new DatagramPacket(msg1, msg1.length, serverip, 9500);
                dataSocket.send(outpacket);

                //socket close
                dataSocket.close();

            }



        } catch (Exception e) {
           
            System.out.println(e.getMessage());
        }
    }
}

 

'개발 언어 > JAVA' 카테고리의 다른 글

18. JDBC  (0) 2024.04.01
고객 관리 프로그램 작성  (0) 2024.03.31
16. ParallelStream, Thread  (0) 2024.03.27
15. Operator, Stream  (0) 2024.03.27
14 람다식  (0) 2024.03.25