728x90
300x250

[네트워크(Network)] OSI Layers, DNS, SSL

 

네트워크에 대해서 몇 가지 소개하고자 한다.

 


1. 네트워크 - OSI Layers 소개


OSI Model을 소개하기에 앞서 몇 가지를 소개하고자 한다.

UDP, TCP를 잠시 소개한다.

 

참고로 Windows DNS와 ISC-Bind 9 Server에서는 데이터를 전송하는 타입은 "UDP" 방식을 사용한다.

 

번호

Port Number

(포트 번호)

타입(Type)

설명(Description)

1

53번

UDP

DNS 영역 포트 

 

 

 

 

 

 

번호

타입(Type)

설명(Description)

1

TCP

 전송 제어 프로토콜 (TCP)은 인터넷 프로토콜 제품군의 주요 프로토콜 중 하나이다.

 이것은 인터넷 프로토콜 (IP)을 보완하는 초기 네트워크 구현에서 시작되었다.

 따라서 전체 제품군을 일반적으로 TCP / IP라고합니다.
TCP는 IP 네트워크를 통해 통신하는 호스트에서 실행되는 응용  프로그램간에 8 진수 (바이트) 스트림의 안정적이고 순서가 있으며 오류가 확인 된 전달을 제공한다.
 World Wide Web, 전자 메일, 원격 관리 및 파일 전송과 같은 주요 인터넷 응용 프로그램은 TCP에 의존한다.
신뢰할 수있는 데이터 스트림 서비스가 필요하지 않은 응용 프로그램은 사용자 데이터 그램 프로토콜 (UDP)을 사용할 수 있다.
 사용자 데이터 그램 프로토콜 (UDP)은 신뢰성이 떨어지는 대기 시간을 강조하는 비 연결형 데이터 그램 서비스를
제공한다.

2

UDP

 User Datagram Protocol의 축약어로 컴퓨터가 다른 컴퓨터와 데이터 통신을 하기 위한 규약(프로토콜)의 일종이다.
 UDP는 세계 통신표준으로 개발된 OSI 모형에서 4번째 계층인 전송 계층(Transport Layer)에서 사용하는 규약이다. 

 동일 계층에서 사용하는 또다른 프로토콜로 TCP가 존재한다.

 

표 1-1. OSI Model

 

 

계층명(Layers)

Protocol data unit (PDU)

프로토콜 데이터 유닛(PDU)

호스트 층

(Host Layer)

7. Application Layers

(응용 계층)

Data(데이터)

 웹(HTTP), FTP 등
예) 리소스 공유, 원격 파일 액세스를
포함한 고급 API

6. Presentation Layer

(프리젠테이션 층)

Data(데이터)

네트워킹 서비스와
응용 프로그램 간의 데이터 변환:
문자 인코딩, 데이터 압축 및 암호화 / 해독
 

예)

1. Apple Filing Protocol (AFP)
2. ICA (Independent Computing Architecture), Citrix 시스템 핵심 프로토콜
3. LPP (Lightweight Presentation Protocol)
4. NetWare 핵심 프로토콜 (NCP)
5. NDR (네트워크 데이터 표현)
6. Telnet (원격 터미널 액세스 프로토콜)
7. Tox, Tox 프로토콜은 프레젠테이션 및 응용 프로그램 계층의 일부로 간주되는 경우가 있음.
8. 외부 데이터 표현 (XDR)
9. X.25 패킷 어셈블러 / 디스어셈블러 프로토콜 (PAD)

5. Data Layer (데이터 층)

Data(데이터)

 통신 세션 관리, 즉 두 노드 간의
다중 앞뒤 전송 형태의 지속적인 정보 교환

 

예)

1. ADSP, AppleTalk 데이터 스트림 프로토콜
2. ASP, AppleTalk 세션 프로토콜
3. H.245, 멀티미디어 통신을위한 호 제어 프로토콜
4. ISO-SP, OSI 세션 계층 프로토콜 (X.225, ISO 8327)
5. iSNS, 인터넷 저장 장치 이름 서비스
6. L2F, 레이어 2 포워딩 프로토콜
7. L2TP, 레이어 2 터널링 프로토콜
8. NetBIOS, 네트워크 기본 입력 출력 시스템
9. PAP, 비밀번호 인증 프로토콜
10. PPTP, 지점 간 터널링 프로토콜
11. RPC, 원격 프로 시저 호출 프로토콜
12. RTCP, 실시간 전송 제어 프로토콜
13. SMPP, 짧은 메시지 피어 - 투 - 피어
14. SCP, 세션 제어 프로토콜
15. SOCKS, SOCKS 인터넷 프로토콜, 인터넷 소켓 참조
16. ZIP, 존 정보 프로토콜
17. SDP, 소켓 직접 프로토콜

4. Transport Layer (전송 층)

 Segment(세그먼트),

Diagram(다이어그램)

 세그먼테이션, 확인 및 멀티플렉싱을
포함한 네트워크상의 지점 간
데이터 세그먼트의 안정적인 전송

예)

1. ATP, AppleTalk 트랜잭션 프로토콜
2. CUDP, 순환 UDP
3. DCCP, 데이터 그램 혼잡 제어 프로토콜
4. FCP, 파이버 채널 프로토콜
5. IL, IL 프로토콜
6. MPTCP, 다중 경로 TCP
7. RDP, 신뢰할 수있는 데이터 프로토콜
8. RUDP, 신뢰할 수있는 사용자 데이터 그램 프로토콜
9. SCTP, 스트림 제어 전송 프로토콜
10. SPX, 순차 패킷 교환
11. SST, 구조화 된 스트림 전송
12. TCP, 전송 제어 프로토콜
13. UDP, 사용자 데이터 그램 프로토콜
14. UDP-Lite
15. μTP, 마이크로 전송 프로토콜

미디어 층

(Media Layer)

3. Network Layer (네트워크 층)

 Packet(패킷)

 주소 지정, 라우팅 및 트래픽 제어를 포함한
다중 노드 네트워크의 구조화 및 관리

예)

1. CLNP, Connectionless 모드 네트워크 서비스
2. DDP, 데이터 그램 전달 프로토콜
3. EGP, 외부 게이트웨이 프로토콜
4. EIGRP, 향상된 내부 게이트웨이 라우팅 프로토콜
5. ICMP, 인터넷 제어 메시지 프로토콜
6. IGMP, 인터넷 그룹 관리 프로토콜
7. IPsec, 인터넷 프로토콜 보안
8. IPv4 / IPv6, 인터넷 프로토콜
9. IPX, 인터 네트워크 패킷 교환
10. OSPF, 최단 경로 우선 개방
11. PIM, 프로토콜 독립 멀티 캐스트
12. RIP, 라우팅 정보 프로토콜

2. Data Link (데이터 링크)

Frame(프레임)

물리 계층에 의해 연결된 두 노드 사이의 데이터 프레임의 신뢰성있는 전송

예)

1. 네트워크 계층 데이터 패킷을 프레임으로 캡슐화
2. 프레임 동기화
3. 논리적 링크 제어부(LLC) 계층 : 일부 전송 계층 프로토콜에 의해 제공되는 ARQ 외에도 오류 제어 (Automatic Repeat Request, ARQ), 물리층에 제공된 FEC (오류 수정) 기술 및 오류 탐지 및 패킷 제거는 네트워크 계층을 포함하여 모든 계층에서 제공.

 

4. 데이터 링크 계층 오류 제어 (즉, 오류 패킷의 재전송)는 무선 네트워크 및 V.42 전화 네트워크 모뎀에는 제공되지만 이더넷과 같은 LAN 프로토콜에는 제공되지 않는다.

비트 오류는 짧은 전선에서 드문 경우이기 때문이다.

이 경우, 오류 검출 및 오류 패킷의 제거 만이 제공된다. 흐름 제어, 전송 계층에 제공되는 것 외에 데이터 링크 계층 흐름 제어는 이더넷과 같은 LAN 프로토콜에서는 사용되지 않지만 모뎀과 무선 네트워크에서는 사용된다.

5. MAC (Media Access Control)제어부 계층 :

이더넷 네트워크 및 허브 네트워크에서 충돌 감지 및 재전송을 위한 CSMA / CD 프로토콜 또는
무선 네트워크에서의 충돌 회피를 위한 CSMA / CA 프로토콜과 같이 채널 액세스 제어를위한 다중 액세스 프로토콜
.

6. 물리적 주소 지정 (MAC 주소 지정)
MAC 필터링, STP (Spanning Tree Protocol) 및 SPB (Shortest Path Bridging)를 포함한 LAN 스위칭 (패킷 스위칭)
7. 데이터 패킷 큐 또는 스케줄링
8. 저장 후 전달 전환 또는 컷 쓰루 전환
9. 서비스 품질 (QoS) 제어
10. 가상 LAN (VLAN)

 1. Physical Layers (물리 계층)

 Symbol(부호, 기호)

물리적인 매체를 통한 로우 비트 스트림의
송수신

예)

1. 1-Wire

2. ARINC 818 항공 전자 공학 디지털 비디오 버스
3. 블루투스 물리적 레이어
4. CAN 버스 (컨트롤러 영역 네트워크) 물리 계층
5. DSL
6. EIA RS-232, EIA-422, EIA-423, RS-449, RS-485
7. Etherloop
8 .10BASE-T, 10BASE2, 10BASE5, 100BASE-TX,

100BASE-FX, 100BASE-T, 1000BASE-T, 1000BASE-SX 및 기타 품종을 포함한 이더넷 물리적 계층
9. GSM Um 무선 인터페이스 물리 계층
10. G.hn/G.9960 물리 계층
11. I²C, I²S
12. IEEE 1394 인터페이스
13. ISDN
14. IRDA 물리층
15. ITU 권고안 : ITU-T 참조
16. 모바일 산업 프로세서 인터페이스 물리 계층
17. 변조 초음파
18. 광 전송망 (OTN)
19. SPI
20. SMB
21. SONET / SDH
22. T1 및 기타 T- 캐리어 링크, E1 및 기타 E- 캐리어 링크
23. TransferJet 물리 계층
24. USB 물리 계층
25. 전화 네트워크 모뎀 - V.92
26. 802.11 Wi-Fi 물리 계층의 종류
27. X10

 

 


2. DNS 서버란

 

도메인 네임 시스템(Domain Name System, DNS)은 호스트의 도메인 이름을 호스트의 네트워크 주소로 바꾸거나 그 반대의 변환을 수행할 수 있도록 하기 위해 개발되었다. 특정 컴퓨터(또는 네트워크로 연결된 임의의 장치)의 주소를 찾기 위해, 사람이 이해하기 쉬운 도메인 이름을 숫자로 된 식별 번호(IP 주소)로 변환해준다. 도메인 네임 시스템은 흔히 "전화번호부"에 비유된다. 인터넷 도메인 주소 체계로서 TCP/IP의 응용에서, www.example.com과 같은 주 컴퓨터의 도메인 이름을 192.168.1.0과 같은 IP 주소로 변환하고 라우팅 정보를 제공하는 분산형 데이터베이스 시스템이다.

 

 

그림 2-1. DNS 시스템 구조(사용자 관점)

 



3. SSL(구 TLS)

 

전송 계층 보안 (영어: Transport Layer Security, TLS, 과거 명칭: 보안 소켓 레이어/Secure Sockets Layer, SSL)는 암호 규약이다.
그리고 '트랜스포트 레이어 보안'이라는 이름은 '보안 소켓 레이어'가 표준화 되면서 바뀐 이름이다. 이 규약은 인터넷 같이 TCP/IP 네트워크를 사용하는 통신에 적용되며, 통신 과정에서 전송계층 종단간 보안과 데이터 무결성을 확보해준다.
이 규약은 웹 브라우징, 전자 메일, 인스턴트 메신저, voice-over-IP (VoIP) 같은 응용 부분에 적용되고 있다.

국제 인터넷 표준화 기구(IETF)에 의해 현재 구식(deprecate)으로 간주되어 있다.
최종 갱신은 RFC 5246이고, 최종 갱신 버전은 넷스케이프에서 만든 SSL 표준을 바탕으로 했다.

 


4. 참고자료(Reference)

 

1. UDP - 나무위키, https://namu.wiki/w/UDP, 접속일자 2018-07-28

2. OSI model, Wikipedia, https://en.wikipedia.org/wiki/OSI_model, 접속일자 2018-07-28

3. Data link layer, Wikipedia, https://en.wikipedia.org/wiki/Data_link_layer, 접속일자 2018-07-28

4. Physical layer, Wikipedia, https://en.wikipedia.org/wiki/Physical_layer, 접속일자 2018-07-28

5. Network layer, Wikipedia, https://en.wikipedia.org/wiki/Network_layer, 접속일자 2018-07-28

6. Transport layer, Wikipedia, https://en.wikipedia.org/wiki/Transport_layer, 접속일자 2018-07-28

7. Session layer, Wikipedia, https://en.wikipedia.org/wiki/Session_layer, 접속일자 2018-07-28

8. Presentation layer, Wikipedia, https://en.wikipedia.org/wiki/Presentation_layer, 접속일자 2018-07-28

9. 도메인 네임 시스템, Wikipedia, https://ko.wikipedia.org/wiki/도메인 네임 시스템, 접속일자 2018-07-28

10. 전송 계층 보안, Wikipedia, https://ko.wikipedia.org/wiki/전송 계층 보안, 접속일자 2018-07-28

반응형
728x90
300x250

[네트워크(Networks)] C#, C++, Java에서의 소켓 프로그래밍

이번에 소개할 것은 C#, C++, Java에서 소켓 프로그래밍을 사용하는 방법에 대해서 소개한다.


1. 소스코드

C#에서의 소켓 프로그래밍 작성 예시이다.
IPv4 환경에서 확인함.

운영체제: Microsoft Windows 10
소프트웨어: Visual Studio Community 2015

 


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace Example
{
    class ServerSide
    {
        public string data = null;

        public void listenSocket()
        {
            byte[] buf;
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 8088);

            server.Bind(ipEndPoint);
            server.Listen(10);

            System.Console.WriteLine("연결 요청(Connection Request)");

            // 클라이언트 연결 받음.
            Socket client = server.Accept();

            // 클라이언트의 데이터 - 보내기 / 받기
            buf = new byte[1024];
            client.Receive(buf);

            System.Console.WriteLine(Encoding.Default.GetString(buf));

        }
    }

    class ClientSide
    {
        public void listenSocket()
        {
            //IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            //IPAddress ipAddress = ipHostInfo.AddressList[0];
            // IPEndPoint ipep = new IPEndPoint(ipAddress, 8088);

            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8088);
            String buf;
            Byte[] data;
           
            Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            client.Connect(ipep);

            Console.WriteLine("소켓 연결(Socket connect)");

            // 데이터 자료 바이트 형으로 받아오기
            data = new byte[1024];
            client.Receive(data);

            // 형 변환 -> getString() 형으로 인코딩
            buf = Encoding.Default.GetString(data);

            Console.WriteLine(buf);

            buf = "소켓 접속 확인 됐습니다.";
            data = Encoding.Default.GetBytes(buf);

            client.Send(data);
            client.Close();

            Console.WriteLine("아무 키나 눌러주세요.");
            Console.ReadLine();

        }
    }
}
 

 NetworkSide.cs

 

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;

 namespace Example
 {
       class Program
       {
               static void Main(string[] args)
               {
                       ServerSide serverside = new ServerSide() ;
                       serverside.listenSocket();
               }
       }
 } 

Program.cs

[첨부(Attachment)]
network_csharp.7z


2. (Gpp)C++에서의 소켓 프로그래밍 작성 예시입니다. (리눅스에서만 가능)

C언어로 구현된 소켓 프로그래밍을 C++에서도 지원이 가능한 형태로 제작하였다.
IPv4 기반에 맞춰 작성함.

 

 

 

운영체제: 우분투(Ubuntu 16.04)
소프트웨어: Gpp, Gcc

 

 

/*
 *   Network.h
 */

 #include <iostream>
 #include <unistd.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <arpa/inet.h>

 using namespace std;

 #ifndef SERVER_H_
 #define SERVER_H_

 // 0.
 class INetwork{
       virtual void listenSingleSocket() = 0;
 };

 // 1. 서버사이드(Server-Side)
 class Server : public INetwork{

 protected:

 private:
     int welcomeSocket, newSocket;

 public:
     Server(){
            this->welcomeSocket = 0;
            this->newSocket = 0;
     }

     void listenSingleSocket(){

           char buffer[1024];
           struct sockaddr_in serverAddr;
           struct sockaddr_storage serverStorage;
           socklen_t addr_size;

           welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);

           serverAddr.sin_family = AF_INET;
           serverAddr.sin_port = htons(8000);
           serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

           int i = 0;

           while(i < sizeof(serverAddr.sin_zero) ){
                 serverAddr.sin_zero[i] = '\0';
                 i++;
           }

           bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr) );

           if ( listen(welcomeSocket, 5) == 0 ){
                  cout << "Listening\n";
           }
           else
          {
                 cout << "Error\n";
          }

           addr_size = sizeof(serverStorage);
           newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);

           buffer[0] = 'H';
           buffer[1] = 'e';
           buffer[2] = 'l';
           buffer[3] = 'l';
           buffer[4] = 'o';

           send(newSocket, buffer, 13, 0);

     }

 };

 class Client : public INetwork{

 private:
         int clientSocket;
         char buffer[1024];
         struct sockaddr_in serverAddr;
         socklen_t addr_size;

 public:
         Client(){
               this->clientSocket = 0;
         }

         void listenSingleSocket(){

              clientSocket = socket(PF_INET, SOCK_STREAM, 0);

               serverAddr.sin_family = AF_INET;
               serverAddr.sin_port = htons(8000);

               serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

               int i = 0;
               while (i < sizeof(serverAddr.sin_zero)){
                      serverAddr.sin_zero[i] = '\0';
                       i++;
               }

                addr_size = sizeof(serverAddr);

                connect(clientSocket, (struct sockaddr *) &serverAddr, addr_size);

                // 문자열 전달 받음 - (unsigned) char[1024]
                recv(clientSocket, buffer, 1024, 0);
                cout << "데이터 전송 받은 문자:" << buffer << endl;
          }

};

#endif /* SERVER_H_ */

 Network.h

 #include <iostream>
 #include "Network.h"

 using namespace std;

 int main() {
        /*
        Server *server = new Server();
        server->listenSingleSocket();
        */

       Client *client = new Client();
       client->listenSingleSocket();
       return 0;
 }

 Program.cpp

[첨부(Attachment)]
Network-gpp.zip


3. 자바에서의 소켓 프로그래밍

싱글 쓰레드 타입으로 작성함. IPv4 환경에서 확인하였다.
IPv6는 확인하지 못함.

 

 

 

운영체제: Microsoft Windows 10 
소프트웨어: Eclipse Luna, JDK 1.81

 

 
 package Network;

 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.net.Socket;
 import java.net.UnknownHostException;

 public class ClientSide implements IHost{
 
        private Socket socket;
        private Host host;
 
        public ClientSide(){
            socket = null;
            host = null;
        }
 
        public Host getHost(){
            return host;
        }
 
        public void setHost(Host host){
            this.host = host;
        }
 
        public void listenSocket(){
  
            InputStream in = null;
            OutputStream out = null;
  
            BufferedReader br = null;
            BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
            PrintWriter pw = null;
  
            String myMsg = null;  // 전달 메시지
            String echo = null;  // 받은 메시지
  
            try{
                 socket = new Socket( host.getIP() , host.getPort() );
    
                 in = socket.getInputStream();
                 out = socket.getOutputStream();
   
                 pw = new PrintWriter(new OutputStreamWriter(out));
                 br = new BufferedReader(new InputStreamReader(in));
   
                while((myMsg = input.readLine()) != null){
    
                      if ( myMsg.equals("/q")){
                            break;
                      }
    
                      pw.println(myMsg);
                      pw.flush();
    
                      echo = br.readLine();
                      System.out.println( "서버사이드 받은 메시지:" + echo );
     
                }
   
                pw.close();
                br.close();
                socket.close();
   
        }
        catch(UnknownHostException e){
                System.out.println("미확인 호스트: " + host.getIP() + ":" + host.getPort() );
                System.exit(-1);
        }
        catch(IOException e){
                System.out.println("입출력 안됨.");
                System.exit(1);
        }

    }
 
}

 ClientSide.java

 
 package Network;

 interface IHost{
        void setHost(Host host);
        Host getHost();
 }

 public class Host{
 
        private String ip;
        private int port;
 
        public Host(int port){
              ip = "";
              this.port = port;
        }
 
        public Host(String ip, int port){
                this.ip = ip;
                this.port = port;
        }
 
        public String getIP(){
                return this.ip;
        }
 
        public int getPort(){
                return this.port;
        }
 
 }

 Host.java

 
 package Network;

 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.net.ServerSocket;
 import java.net.Socket;

class ClientWorker implements Runnable{

         private int id;
         private Socket client;
         private String line;
 
         public ClientWorker(Socket client, int id){

              this.client = client;
              this.id = id;
         }
 
         public void run() {
  
             InputStream in = null;
             OutputStream out = null;
  
             PrintWriter pw = null;
             BufferedReader br = null;
  
             String recvStr = "";

             try{
                 in = client.getInputStream();
                 out = client.getOutputStream();
   
                 pw = new PrintWriter(new OutputStreamWriter(out));
                 br = new BufferedReader(new InputStreamReader(in));
   
             }catch(IOException e){
                 System.out.println("읽기 실패(Read Failed)");
                 System.exit(-1);
             }

             try {
   
                  while( (recvStr = br.readLine() ) != null ){
    
                        appendText(recvStr);
                        System.out.print( "쓰레드(Thread)" + id + ":" );
                        System.out.println(line);
                        pw.println(recvStr);
                        pw.flush();
                  }
   
                  client.close();
   
             } catch (IOException e) {
                   System.out.println("읽기 실패(Read Failed");
                   System.exit(-1);
             }
  
       }
 
        // 동기화 추가
        public synchronized void appendText(String strText){
  
              if ( line == null )
              {
                   line = strText;
              }
              else{
                   line = line + strText;
              }
        }
 
 }

 public class ServerSide implements IHost{

         private ServerSocket server;
         private Socket client;
         private Host host;
         private static int clientID;
 
         public ServerSide(){
                server = null;
                client = null;
                host = null;
                clientID = 0;
         }
 
         public Host getHost(){
                return host;
          }
 
          public void setHost(Host host) {
                 this.host = host;
          }
 
          // 싱글(Single)
          public void listenSingleSocket(){

                String line;
   
                InputStream in = null;
                OutputStream out = null;
  
                PrintWriter pw = null;
                BufferedReader br = null;
  
                String recvStr = null;
  
                try{   
                      server = new ServerSocket( host.getPort() ); 
                }
                catch(IOException e){
                      System.out.println("포트 " + host.getPort() + "번은 응답하지 않습니다.");
                      System.exit(-1);
                }
  
                try{
                      client = server.accept();
                }
                catch(IOException e){
                      System.out.println("응답 실패: 포트 " + host.getPort() + "번");
                      System.exit(-1);
                }
  
                try{
                      in = client.getInputStream();
                      out = client.getOutputStream();
   
                      pw = new PrintWriter(new OutputStreamWriter(out));
                      br = new BufferedReader(new InputStreamReader(in));
   
                }catch(IOException e){
                      System.out.println("읽기 실패(Read Failed)");
                      System.exit(-1);
                }

                try {
   
                     while( (recvStr = br.readLine() ) != null ){
     
                            System.out.print( "싱글" );
                            pw.println(recvStr);
                            pw.flush();
                    }
   
                   client.close();
                   server.close();
   
              } catch (IOException e) {
                     System.out.println("읽기 실패(Read Failed");
                     System.exit(-1);
              }
  
         }

        // 멀티(Multi-Threading)
        public void listenMutliSocket(){
   
              ClientWorker w = null;

              try{
                  server = new ServerSocket( host.getPort() ); 
              }
              catch(IOException e){
                  System.out.println("포트 " + host.getPort() + "번은 응답하지 않습니다.");
                  System.exit(-1);
              }
  
              try{
                   while(true){
   
                        w = new ClientWorker( server.accept(), clientID++ );
  
                        Thread t = new Thread(w);
                        t.start();
                   }
   
             }
             catch(IOException e){
                  System.out.println("응답 실패: 포트 " + host.getPort() + "번");
                  System.exit(-1);
             }
  
       }
  
       protected void finalize(){
  
             try{
                  server.close();
             }catch(IOException e){
                  System.out.println("소켓을 종료할 수 없습니다.");
                  System.exit(-1);
             }
  
       }

 }

 ServerSide.java

 package Network;

 public class Example{
 
        public static void main(String[] args){
  
             ServerSide server = new ServerSide();
             Host host = new Host(10001);
             server.setHost(host);
             server.listenMutliSocket();
        }
 }

 Example.java

[예제 - 첨부(Attachment)]
Network.zip


4. IPv4와 IPv6

 

네트워크와 관련된 주제로 IPv4와 IPv6에 대해서 소개한다.

 4-1. IPv4 

 IPv4는 인터넷 프로토콜의 4번째 판이며, 전 세계적으로 사용된 첫 번째 인터넷 프로토콜이다.

 과거에 인터넷에서 사용되는 유일한 프로토콜이였으나 오늘날에는 IPv6이 대중화되었다. IETF RFC 791(1981년 9월)에 기술되어 있다.

 IPv4는 패킷 교환 네트워크 상에서 데이터를 교환하기 위한 프로토콜이다. 데이터가 정확하게 전달될 것을 보장하지 않고,
 중복된 패킷을 전달하거나  패킷의 순서를 잘못 전달할 가능성도 있다. 데이터의 정확하고 순차적인 전달은 그보다 상위 프로토콜인
 TCP에서(그리고 UDP에서도 일부) 보장한다.

 IPv4의 주소체계는 총 12자리이며 네 부분으로 나뉜다. 각 부분은 0~255까지 3자리의 수로 표현된다. IPv4 주소는 32비트로 구성되어 있으며,
 현재 인터넷 사용자의 증가로 인해 주소공간의 고갈에 대한 우려가 높아지고 있다. 이에 따라 대안으로 128비트 주소체계를 갖는 IPv6가 등장하였다.

 중국의 경우 주소공간 고갈을 우려하여 일부에서 독자적으로 IPv9(십진제 인터넷 주소체계)과 숫자도메인(Digital Domain Name System, DDNS)이
 결합된 개념인 IP 주소와 도메인 이름이 동일한 네트워크 체제인 All-Digital-Domain-Address (ADDA)를 사용하기도 한다.

 2011년 2월 4일부터 모든 IPv4 주소가 소진되어 IPv4의 할당이 중지되었다.

 

CLASS 구성 범위
A 클래스 xxx.xxx.xxx.xxx 1.0.0.1 ~ 126.255.255.254 61.211.123.22
B 클래스 xxx.xxx.xxx.xxx 128.0.0.1 ~ 191.255.255.254 181.123.211.33
C 클래스 xxx.xxx.xxx.xxx 192.0.0.1 ~ 223.255.255.254 221.23.222.222
D 클래스 224.0.0.0 ~ 239.255.255.255
E 클래스 240.0.0.0 ~ 254.255.255.254

 그림 4-1-1. 쿼드 점으로 구분 된 IPv4 주소 표현을 이진 값으로 분해.

 이건 조금 해결할 수는 있을 듯하다. 다만 이것도 계산이 더럽다고 볼 수 있다.
 아래는 172에 대해서 해결한 것이다.

10 |  10  |  110  | 0  

  10 = | Flag |
  128번 = 000000
  129번 = 000001

   .........
  172번 = 101100

 

 4-2. IPv6

 인터넷 프로토콜 버전 6 (IPv6)은 네트워크상의 컴퓨터에 대한 식별 및 위치 시스템을 제공하고 인터넷을 통해 트래픽을 라우팅하는
 통신 프로토콜 인 IP (인터넷 프로토콜)의 최신 버전이다.

 
IPv6는 오랫동안 예상되었던 IPv4 주소 고갈 문제를 해결하기 위해 IETF (Internet Engineering Task Force)에서 개발되었다.
 
IPv6은 IPv4를 대체하기 위한 것이다. IPv6는 1998 년 12 월에 초안 표준이되었고, 2017 년 7 월 14 일에 인터넷 표준이 되었다.

 인터넷상의 모든 장치에는 식별 및 위치 정의를 위해 고유 한 IP 주소가 할당된다.
 
1990 년대의 상용화 이후 인터넷의 급속한 성장으로 인해 IPv4 주소 공간보다 장치를 연결하는 데 훨씬 많은 주소가 필요할 것이다.

 
1998 년까지 IETF (Internet Engineering Task Force)는 후임 프로토콜을 공식화했다.
 
IPv6은 128 비트 주소를 사용하며 이론적으로 2128 개 또는 약 3.4 × 1038 개 주소를 허용한다.

 
여러 개의 범위가 특수 용도로 예약되었거나 완전히 사용되지 않도록 실제 숫자가 약간 더 작다.
 
가능한 IPv6 주소의 총 수는 32 비트 주소를 사용하고 약 43 억 개의 주소를 제공하는 IPv4의 7.9 × 1024 배이다.
 
 
이 두 프로토콜은 상호 운용성을 위해 설계되지 않았기 때문에 IPv6 로의 전환이 복잡해졌다.
 
그러나 IPv4와 IPv6 호스트 간의 통신을 허용하기 위해 몇 가지 IPv6 전환 메커니즘이 고안되었다.

 IPv6은 더 큰 주소 지정 공간 외에도 다른 기술적 이점을 제공한다.
 
특히 인터넷을 통한 경로 집계를 용이하게 하는 계층적 주소 할당 방법을 허용하므로 라우팅 테이블의 확장을 제한한다.
 
멀티 캐스트 주소 사용은 확장되고 단순화되며 서비스 제공을위한 추가 최적화를 제공한다.

 장치의 이동성, 보안 및 구성 측면이 프로토콜 설계시 고려되었다.

 IPv6 주소는 그룹이 콜론으로 구분 된 네 개의 16 진수 8 개의 그룹으로 표시된다.
 (예: 2001:0db8:0000:0042:0000:8a2e:0370:7334).이 전체 표기법을 줄이는 방법이 있다.

 

그림 4-2-1. IPv6 주소 표현을 이진 형식으로 분해

 IPv6를 사람 손으로 푼다고 하면, 매우 많은 노가다가 필요하다.
 각 옥탯에 있는 16진수를 일일이 하나 하나씩 해결해야 한다.

4-3. IPv6의 패킷헤더

 



그림 4-3-1. IPv6의 패킷해더

 IPv6의 패킷해더이다. IPv6로 데이터를 송수신하면 이런 형태로 전송이 되는 것을 관찰할 수 있다.
 리눅스에 패킷 분석 툴킷이 있는데 한번 패킷해더를 추적해봐도 좋을 것이다. 

 이 패킷해더를 관찰하는 대표적인 툴킷(Tool-kits)으로 WireShark가 있다.

  
 그림 4-3-2. WireShark 시연 예

 [IPv4 to IPv6에 관한 이야기]

 IPv6를 실제로 사용하려면 많은 조건이 필요하다.
 IPv4에서 IPv6로 변환해줄 수 있는 변환장치 등이 필요하다.
 터널링도 하나의 기법이 될 수 있다.


5. 참고자료(Reference)

 

1. IPv4, Wikipedia, https://ko.wikipedia.org/wiki/IPv4, Accessed by 2018-07-27
2. IPv6, Wikipeida, https://en.wikipedia.org/wiki/IPv6, Accessed by 2018-07-27
3. IPv6 OSPFv3 ESP Packets and Decrypting with Wireshark, https://packetpushers.net/ipv6-ospfv3-esp-packets-and-decrypting-with-wireshark/, Accessed by 2018-07-27

반응형

+ Recent posts