1. 네트워킹(Networking)
- 네트워킹(Networking): 두 대 이상의 컴퓨터를 케이블로 연결해서 네트워크를 구성하는 것을 말한다.
- 초기의 네트워크는 몇 대의 컴퓨터로 구성됐으나 현재는 셀 수 없을 정도로 많은 컴퓨터가 인터넷이라는 하나의 거대한 네트워크를 구성하고 있으며 인터넷을 통해 다양하고 방대한 양의 데이터를 공유 가능하다.
- 자바의 java.net 패키지를 이용하면 네트워크 애플리케이션의 데이터 통신 부분을 쉽게 작성 가능
1.1 클라이언트(client)와 서버(server)
- 클라이언트와 서버는 컴퓨터간의 관계를 역할로 구분하는 개념이다.
- 서버(server): 서비스를 제공하는 컴퓨터
- 보통적으로 서버는 다수의 클라이언트에게 서비스를 제공하기 때문에 고사양의 하드웨어를 갖춘 컴퓨터이다.
- 서비스: 서버가 클라이언트로부터 요청 받은 작업을 처리하고 그 결과를 제공하는 것을 말한다.
- 파일 서버(file server): 클라이언트가 요청한 파일은 제공하는 서비스를 수행한다.
- 메일 서버(mail server):
- 어플리케이션 서버(application server)
- 일반 PC는 주로 클라이언트 역할이지만, FTP Serv-U 같은 FTP 서버프로그램이나 Tomcat 같은 웹 서버 프로그램을 설치하면 서버 역할을 수행할 수 있다.
- 클라이언트(client): 서비스를 사용하는 컴퓨터
- P2P(peer to peer) 모델: 별도의 전용 서버 없이 각 클라이언트가 서버 역할을 동시에 수행하는 모델이다.
- 소리바다, 푸르나 같은 파일 공유 프로그램은 클라이언트 프로그램, 서버프로그램을 하나로 합친 것이다.
- 이를 설치한 컴퓨터는 클라이언트인 동시에 서버가 되므로 회원끼리 서로 파일을 주고 받을 수 있다.
서버 기반 모델과 P2P 모델의 차이점
- 서버 기반 모델(Server based model): 네트워크를 구축할 때 전용 서버를 두는 모델
- 안정적 서비스 제공
- 공유 데이터의 관리와 보안이 용이하다.
- 서버 구축 비용과 관리 비용이 든다.
- P2P(peer to peer) 모델: 별도의 전용 서버 없이 각 클라이언트가 서버 역할을 동시에 수행하는 모델이다.
- 서버 구축, 관리 비용 절감
- 자원 활용을 극대화
- 보안 취약하다.
- 자원 관리가 어려움
1.2 IP 주소(IP address)
- IP 주소는 컴퓨터(host, 호스트)를 구별하는데 사용되는 고유한 값으로 인터넷에 연결된 모든 컴퓨터는 IP 주소를 갖는다.
- 4 byte(32 bit)의 정수로 구성된다.
- IP 주소는 호스트 주소(24bit)와 네트워크 주소(8bit)로 구성된다.
- 호스트 주소가 0이면 자신을 나타낸다.
- 서로 다른 두 호스트의 IP 주소의 네트워크 주소가 같은 경우는 두 호스트가 같은 네트워크에 포함됐다는 뜻이다.
- 예를 들어, 하나의 무선 공유기로 여러 대의 스마트폰, 노트북을 연결하고 IP 주소를 조회하면 같은 IP 주소가 나온다.
- IP 주소와 서브넷 마스크(Subnet Mask)를 비트연산자로 '&' 연산하면 IP 주소에서 네트워크 주소만을 뽑아낼 수 있다.
1.3 InetAddress
- Java에서는 IP 주소를 다루기 위한 클래스로 InetAddress 를 제공한다.
- 하나의 도메인명(ex. www.naver.com)에 여러 IP 주소가 매핑될 수도 있고 그 반대의 경우도 가능하기 때문에 전자의 경우는 getAllByName()을 통해 모든 IP 주소를 얻을 수 있다.
- getLocalHost()를 사용하면 호스트명과 IP 주소를 알아낼 수 있다.
1.4 URL (Uniform Resource Locator)
- Def) URL(Uniform Resource Locator)는 인터넷에 존재하는 여러 자원에 접근 가능한 주소를 표현하기 위한 것이다.
- ex) http://www.codechobo.com:80/sample/hello.html?referer=codechobo#index1
- 프로토콜: 자원에 접근하기 위해 서버와 통신하는데 사용하는 규약(http)
- 호스트명: 자원을 제공하는 서버의 이름 (www.codechobo.com)
- 포트번호: 통신에 사용되는 서버의 포트 번호(80) http 프로토콜에서는 80번 포트를 사용한다. 이를 생략하면 80번으로 간주한다.
- 경로명: 접근하려는 자원이 저장된 서버상의 위치(/sample/)
- 파일명: 접근하려는 자원의 이름 (hello.html)
- 쿼리(query): URL에서 '?' 이후의 부분 (referer=codechobo)
- 참조(anchor): URL에서 '#' 이후의 부분(index1)
1.5 URLConnection
- URLConnection은 애플리케이션과 URL간의 통신 연결을 나타내는 클래스의 최상위 클래스로 추상 클래스이다.
- 하위 클래스로 HttpURLConnection, JarURLConnection이 있다.
2. 소켓 프로그래밍
- Def) 소켓 프로그래밍은 소켓을 이용한 통신 프로그래밍을 뜻한다.
- Def) 소켓(socket): 프로세스 간의 통신에 사용되는 양쪽 끝단(endpoint)을 의미한다.
- java.net 패키지를 통해서 소켓 프로그래밍을 지원한다.
- 소켓 통신에 사용되는 프로토콜에 따라서 다른 종류의 소켓을 구현해서 제공한다.
2.1 TCP(Transfer Control Protocol)와 UDP(User Datagram Protocol)
- TCP/IP 프로토콜은 이기종 시스템간의 통신을 위한 표준 프로토콜로 프로토콜의 집합이다.
- OSI 계층의 전송 계층(transfer layer)에 해당한다.
- 어플리케이션의 특성에 따라 선택해서 사용한다.
항목 | TCP | UDP |
연결 방식 | 연결 기반(connection-oriented) - 연결 후 통신(전화기) - 1:1 통신 방식 |
비연결 기반(connectionless-oriented) - 연결 없이 통신 - 1:1, 1:n, n:n 통신 방식 |
특징 | 데이터의 경계를 구분하지 않는다. 신뢰성있는 데이터 전송 - 데이터 전송 순서 보장 - 데이터의 수신 여부를 확인 -> 손실 시, 재전송 - 패킷 관리할 필요 없다. - UDP 보다 느림 Ex) 파일 전송 |
데이터의 경계를 구분한다. (Datagram) 신뢰성 없는 데이터 전송 - 데이터의 전송 순서가 바뀔 수 있다. - 데이터의 수신 여부를 확인하지 않는다. -> 데이터 손실 여부 알 수 없음 - 패킷을 관리해줘야한다. - TCP보다 빠름 (수신 여부를 확인하지 않아서) Ex) 동영상 스트리밍 |
관련 클래스 | Socket ServletSocket |
DatagramSocket DatagramPacket MultocastSocket |
2.2 TCP 소켓 프로그래밍
- TCP 소켓 프로그래밍은 클라이언트와 서버 간의 일대일 통신이다.
- 서버소켓(ServerSocket) 은 포트와 결합되어 포트를 통해서 원격 사용자의 연결 요청을 기다리다가 요청이 올 때마다 새로운 소켓을 생성해서 상대편 소켓과 통신할 수 있도록 연결한다.
- 서버 소켓은 연결만 처리한다.
- 실제적인 데이터 통신은 서버소켓과 관계없이 소켓과 소켓 간에 이뤄진다.
- 소켓들이 데이터를 주고받는 연결 통로는 바로 입출력스트림이다.
- 서버소켓은 전화 교환기, 소켓은 전화기에 비유 가능
- 서버소켓은 포트를 독점한다. 반면에, 소켓은 하나의 포트 번호를 공유해서 사용 가능하다.
- 포트는 호스트가 외부와 통신을 하기 위한 통로로 하나의 호스트가 65536(포트 번호는 0~65535에 속하는 값이다.)개의 포트를 가지고 있다.
- 보통 1023번 이하의 포트는 다른 프로그램에 의해 사용되는 경우가 많으니 1023 이상의 번호 중에서 사용하지 않느 번호를 사용해야한다.
- 소켓은 위와 같이 두 개의 스트림(InputStream, OutputStream)을 가지고 있다.
- 스트림들은 반대편 소켓의 스트림들과 교차 연결된다.
Java 소켓 관련 클래스
- Socket: 프로세스간의 통신을 담당하며 InputStream, OutputStream을 가지고 있다. 두 스트림을 통해서 프로세스간의 통신(입출력)이 이뤄진다.
- ServletSocket: 포크와 연결되서 외부의 연결 요청이 들어오면 socket을 생성해서 소켓 간 통신이 이뤄지도록 한다. 한 포트에 한 ServerSocket만 연결 가능하다.
- 프로토콜이 다르면 같은 포트를 공유가능하다.
서버 프로그램과 클라이언트 프로그램의 통신 과정
- 서버 프로그램에서는 서버소켓을 사용해서 서버 컴퓨터의 특정 포트에서 클라이언트의 연결 요청을 처리할 준비를 한다.
- 클라이언트 프로그램은 접속할 서버의 IP 주소와 포트 정보를 가지고 소켓을 생성해서 서버에 연결을 요청한다.
- 서버소켓은 클라이언트의 연결 요청을 받으면 서버에 새로운 소켓을 생성해서 클라이언트의 소켓과 연결되도록 한다.
- 이제 클라이언트의 소켓과 새로 생성된 서버의 소켓은 서버 소켓과 관계 없이 일대일 통신을 한다.
Ex) TCP
2.3 UDP 소켓 프로그래밍
- TCP 소켓 프로그래밍에서는 Socket과 ServerSocket을 사용하지만 UDP소켓 프로그래밍에서는 DatagramSocket과 DatagramPacket을 사용한다.
- UDP는 연결 지향이 아니므로 ServerSocket가 필요없다.
- UDP 통신에서 DatagramSocket를 사용하고 데이터를 DatagramPacket에 담아서 전송한다.
- DatagramPacket: 헤더(패킷을 수신한 호스트의 정보) + 데이터
- 패킷을 전송하면 DatagramPacket에 지정된 주소의 DatagramSocket에 도착한다.
Ex) UdpClient
- 주의: UdpServer를 먼저 실행한다음에 UdpClient를 실행한다.
<hide/>
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();
}
}
}
Note) 실행 결과
- 다음과 같이 터미널에서 실행해준다.
Ex) UdpServer
<hide/>
public class UdpServer {
public void start() throws IOException, BindException {
// Port 7777번을 사용하는 소켓을 생성한다.
DatagramSocket socket = new DatagramSocket(7777);
DatagramPacket inPacket, outPacket;
byte[] inMsg = new byte[10];
byte[] outMsg;
while (true) {
// 데이터를 수신하기 위한 패킷을 생성한다.
inPacket = new DatagramPacket(inMsg, inMsg.length);
// 패킷을 통해 데이터를 수신한다.
socket.receive(inPacket);
// 수신한 패킷으로부터 client 의 IP 주소, port 번호를얻는다.
InetAddress address = inPacket.getAddress();
int port = inPacket.getPort();
// 서버의 현재 시간을 출력
SimpleDateFormat sdf = new SimpleDateFormat("[hh:mm:ss]");
String time = sdf.format(new Date());
outMsg = time.getBytes(); // 서버의 시간을 byte 배열로 변환한다.
// 패킷을 생성해서 클라이언트에게 패킷 전송
outPacket = new DatagramPacket(outMsg, outMsg.length, address, port);
socket.send(outPacket);
}
}
public static void main(String[] args) {
try {
new UdpServer().start(); // UDP 서버를 실행
} catch (IOException e) {
e.printStackTrace();
}
}
}
- 오류: java.net.BindException
- 원인 : 해당 포트가 이미 사용중일 때 발생하는 예외이다.
- 해결
- cmd 창에서 다음 명령어로 내가 사용하고 있는 port 번호와 PID를 확인한다.
- 현재 UdpServer 클래스에서 7777번 포트를 쓰고 있으니까 PID 번호를 이용해서 kill 하면 된다.
- taskkill /f /pid (PID번호) 입력하고 나면 다음과 같이 프로세스가 종료되었다고 나온다.
Note) 실행 결과
- 서버로부터 서버 시간을 전송 받아서 출력하는 UDP 클라이언트와 서버 프로그램이다.
- 클라이언트가 DatagramPacket을 생성해서 DatagramSocket으로 서버에 전송하면 서버는 전송 받은 DatagramPacket의 getAddress(), getPort()를 호출해서 클라이언트의 정보를 얻어서 서버시간을 패킷에 담아 전송
모르는 부분 및 기타
- FTP(File Transfer Protocol, 파일 전송 프로토콜): TCP/IP 프로토콜을 가지고 서버와 클라이언트 사이의 파일 전송을 위한 프로토콜이다. TCP/IP 프로토콜 테이블의 응용 계층에 속한다.
- Telnet(텔넷, tel 통신 + net 네트워크): 사용자의 컴퓨터에서 네트워크를 이용해서 원격지에 떨어진 서버에 접속해서 자료를 교환할 수 있는 프로토콜을 말한다. 자신의 컴퓨터처럼 사용 가능하다.
- 요즘은 보안상 문제(데이터가 암호화되지 않는다.) 때문에 SSH를 많이 사용한다.
- 주요 네트워크 프로토콜 중 하나이다.
- 포트번호 23번
- SSH(Secure SHell, 시큐어 셸): 네트워크 상의 다른 컴퓨터에 로그인하거나 원격 시스템에서 명령을 실행하고 다른 시스템으로 파일을 복사할 수 있도록 해주는 응용 프로그램 또는 프로토콜을 말한다.
- Telnet과 SSH는 기능이 비슷하다.
- 암호화 통신을 하기 때문에 비교적 안전하다.
- 포트번호 22번
- 서브넷 마스크(Subnet Mask): 서브넷을 구분하는 방법 중 하나이다.
- 네트워크 패킷(Network packet, 패킷): 컴퓨터 네트워크가 전달하는 데이터의 형식화된 블록이다.
- 제어 정보와 사용자 데이터로 이뤄진다.
- 데이터의 전송 단위이다.
- PID(Process ID, 프로세스 식별자): OS에서 프로세스를 식별하기 위해 부여하는 번호이다.
출처 - 「Java의 정석 - 남궁성」
참고 링크)
'Java > Java의 정석' 카테고리의 다른 글
Chapter 13 스레드(Thread) (0) | 2023.03.01 |
---|---|
Chapter 15 입출력 I/O (0) | 2022.03.07 |
Chapter 14 람다와 스트림 (0) | 2022.03.04 |
Chapter 12 지네릭스, 열거형, 에너테이션 (0) | 2022.03.02 |
Chapter 11 컬렉션 프레임웍(Collection Framework) (0) | 2022.03.02 |