Java Project : 14_network
Package : network
Class : InetAddressMain.java
네트워크
네트워크는 여러 컴퓨터들을 통신회선으로 연결한 것이다.
서버 : 서비스를 제공하는 프로그램
클라이언트 : 서비스를 요청하는 프로그램
IP
컴퓨터에도 고유한 주소가 있는데 그것이 IP이다.
IP주소는 네트워크 어댑ㅌ마다 할당된다.
IP 주소는 xxx.xxx.xxx.xxx 형식이고 숫자는 0~255 사이의 정수값이다.
Ip 주소를 모르면 서로 통신할 수 없다. 그래서 DNS(Domain Name System)를 이용해서 컴퓨터의 IP 주소를 검색할 수 있다.
하나의 주소록을 DNS라고 한다.
홍길동(도메인) → 010-1234-5678(IP)
도메인을 주면 IP주소로 바꿔준다.
도메인 : naver.com / 네이버
DNS를 통해서 IP로 바꿔준다.
도메인은 일반사용자가 편하게 사용할 수 있도록 하는 것이다.
DNS(Domain Name System)
DNS는 도메인 이름으로 ip를 등록하는 저장소이다.
웹 브라우저(크롬, 사파리)는 웹 서버와 통신하는 클라이언트이다.
사용자가 입력한 도메인으로 DNS에서 IP
Port
Port는 운영체제가 관리하는 서버 프로그램의 연결번호이다.
http → 80
https → 443
oracle → 1521
ftp → 21
이런건 건들면 안 된다.
프로토콜
우리가 전송하기위해서는 규약이 있다.
IP주소로 프로그램들이 통신하기 위해서는 약속된 데이터 전송 규약이 있다.
인터넷에서 전송용 프로토콜은 TCP / UDP 있다.
TCP는 요청하면 반드시 응답이 와줘야한다.
상대방에게 이메일을 보냈으면 읽었는지 안읽었는지 확인할 수 있다. 나에게 응답이 오기때문에 수신확인할 수 있는 것
가면 반드시 와줘야한다.
클라이언트가 연결 요청을 하고 서버가 수락하면 통신 회선이 고정된다.
고정된 회선을 통해 데이터가 전달된다.
보낸 데이터가 순서대로 전달되고 손실이 발생하지 않는다.
EX) 이메일, 파일 전송
ServerSocket – 클라이언트의 연결을 수락하는 서버쪽 클래스에서 작성
생성 시 바인딩할 Port 번호를 지정해야 한다.
accept() 메소드로 연결을 수락하고 Socket를 생성한다.
Socket – 클라이언트에서 연결 요청할 때 사용
클라이언트와 서버에서 데이터를 주고받을 때 사용
Socket
클라이언트와 서버 양쪽에 걸리는 것
클라이언트와 서버에서 데이터를 주고받을 때 사용
양쪽이 있어야한다. 소켓을 핸드폰이라고 생각하면 된다.
UDP는 상대방이 받던 안 받던 던지는 것이다.
영상 데이터가 와도 상대방한테 다시 돌아오던 말던 받던말던 그냥 보내는 것처럼
발신자가 일방적으로 수신자에게 데이터를 보내는 방식이다.
TCP처럼 연결 요청, 수락 과정이 없다.
TCP처럼 하나의 고정회선이 아니라 여러 회선을 통해서 데이터가 전송된다.
그러므로 순서대로 전달되지 않는다.
영상이 한 컷 두 컷 손실되더라도 영상은 계속 수신되므로 문제가 되지 않는다.
DatagramSocket – 발신점과 수신점에 해당
- 객체 생성 시 Port 번호를 주어야 한다.
DatagramPacket – 주고 받는 데이터에 해당
InetAddress - 기본 생성자가 없다.
InetAddress naver = new InetAddress(); //이게 안된다.
아래 처럼 해야한다.
public static void main(String[] args) throws UnknownHostException {
InetAddress naver = InetAddress.getByName("www.naver.com");
}
네이버 IP 출력하기
System.out.println("Naver IP = " + naver.getHostAddress());
Naver IP = 223.130.200.219
가상IP - 강의실 안에서만 쓸 수 있다.
InetAddress local = InetAddress.getLocalHost();
System.out.println("localhost IP = " + local.getHostAddress());
localhost IP = 192.168.0.98
회사마다 IP가 여러개가 있다.
02-1234-5678 ~10
IP가 여러개면 배열타입으로 가져온다.
IP하나다 InetAdderess가 잡혀 들어온다.
InetAddress[] naver2 = InetAddress.getAllByName("www.naver.com");
for(InetAddress data : naver2) {
System.out.println("Naver IP = " + data.getHostAddress());
}
Naver IP = 223.130.192.248
Naver IP = 223.130.192.247
Naver IP = 223.130.200.236
Naver IP = 223.130.200.219
package network;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressMain {
public static void main(String[] args) throws UnknownHostException {
InetAddress naver = InetAddress.getByName("www.naver.com");
System.out.println("Naver IP = " + naver.getHostAddress());
System.out.println();
InetAddress local = InetAddress.getLocalHost();
System.out.println("localhost IP = " + local.getHostAddress());
System.out.println();
InetAddress[] naver2 = InetAddress.getAllByName("www.naver.com");
for(InetAddress data : naver2) {
System.out.println("Naver IP = " + data.getHostAddress());
}
}
}
Naver IP = 223.130.192.248
localhost IP = 192.168.0.98
Naver IP = 223.130.192.248
Naver IP = 223.130.192.247
Naver IP = 223.130.200.236
Naver IP = 223.130.200.219
https://
ftp://
URI
Class : URLMain.java
package network;
import java.net.MalformedURLException;
import java.net.URL;
public class URLMain {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("https://www.naver.com/index.html");
System.out.println("프로토콜 = " + url.getProtocol());
System.out.println("호스트 = " + url.getHost());
System.out.println("포트 = " + url.getPort()); // -1 포트값 기재안했으므로
System.out.println("기본 포트 = " + url.getDefaultPort());
System.out.println("파일 = " + url.getFile());
System.out.println();
}
}
프로토콜 = https
호스트 = www.naver.com
포트 = -1
기본 포트 = 443
파일 = /index.html
페이지 소스 보기
IO Stream
- byte 단위
InputStream
OuputStream
2. 문자 단위
Reader
Writer
URL을 통해서 브라우저에 떴고 그 브라우저로부터 가져오는 것
InputStream
BufferedReader InputStreamReader url.openSream()
URL.java ← buffer ← 컴퓨터 ← 웹 브라우저(크롬)
← 파일
FileReader
← 키보드(System.in)
InputStreamReader
//IO 생성
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
String line = null;
while( (line = br.readLine()) != null ) { //null이 아니면 읽을 값 있다는 거
System.out.println(line);
}
br.close();
일정양을 넘어가면 버퍼크기가 정해져있으므로 앞에가 다 잘려버린다.
package network;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
public class URLMain {
public static void main(String[] args) throws IOException {
URL url = new URL("https://www.naver.com/index.html");
System.out.println("프로토콜 = " + url.getProtocol());
System.out.println("호스트 = " + url.getHost());
System.out.println("포트 = " + url.getPort()); // -1 포트값 기재안했으므로
System.out.println("기본 포트 = " + url.getDefaultPort());
System.out.println("파일 = " + url.getFile());
System.out.println();
//IO 생성
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
String line = null;
while( (line = br.readLine()) != null ) { //null이 아니면 읽을 값 있다는 거
System.out.println(line);
}
br.close();
}
}
Class : Protocol.java
ProtocolServer.java
ProtocolClient.java
ProtocolClient.java
public class ProtocolClient {
Socket socket; //핸드폰이라 생각하기
BufferedReader br;
BufferedWriter bw;
Scanner scan;
//IO생성
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//--------------------
String message, line;
try {
while(true) { //상대가 전화 끊을 때까지 계속 하는 것처럼 무한루프
//서버로 보내기
System.out.println();
System.out.println("종료하려면 200:대화명 이라고 입력하세요 \n");
message = scan.nextLine();
bw.write(message + "\n"); //서버로 보내기
bw.flush(); //버퍼 비워주기 / 그래야 다음 데이터가 또 나갈 수 있다.
//서버로부터 받기
}// while
} catch (IOException e) {
e.printStackTrace();
}
Protocol.java
package network;
public final class Protocol { // final이면 밑에 자식 안생김
public static final String ENTER = "100";
public static final String EXIT = "200";
public static final String SEND_MESSAGE = "300";
}
보내는 문자가 입장이냐 퇴장이냐 메시지냐를 구분하고 싶은 것 !
ProtocolClient.java
try {
while(true) { //상대가 전화 끊을 때까지 계속 하는 것처럼 무한루프
//서버로 보내기
System.out.println();
System.out.println("입장은 100:대화명 이라고 입력하세요");
System.out.println("퇴장은 200:대화명 이라고 입력하세요");
System.out.println("메세지는 300:메세지 이라고 입력하세요\n");
서버로부터 받기
//서버로부터 받기
line = br.readLine();
//200:apple -> "200", "apple"
String [] ar = line.split(":"); //:로 분리해라
if(ar[0].equals("200")) {
br.close();
bw.close();
socket.close();
System.exit(0);
}
//if(ar[0].equals("200")) {
if(ar[0].equals(Protocol.EXIT)) {
//서버로부터 받기
line = br.readLine();
//200:apple -> "200", "apple"
String [] ar = line.split(":"); //:로 분리해라
//if(ar[0].equals("200")) {
if(ar[0].equals(Protocol.EXIT)) {
br.close();
bw.close();
socket.close();
System.exit(0);
}
ProtocolServer.java
public ProtocolServer() {
try {
serverSocket = new ServerSocket(9500); //9500번포트에서 클라이언트가 올 때까지 기다린다.
System.out.println("서버준비완료..");
socket = serverSocket.accept(); //클라이언트를 낚아채서 클라이언트와 대화할 소켓을 생성한다.
//클라이언트 들어오기 전까지는 멈춰있다.
//IO생성
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
System.out.println("클라이언트와 연결이 안되었습니다.");
e.printStackTrace();
System.exit(0);
}
if(ar[0].equals(Protocol.ENTER)) {//입장 => 100:대화명
bw.write(ar[0] + "님이 입장하였습니다.\n");
bw.flush();
}else if(ar[0].equals(Protocol.EXIT)) { //퇴장 => 200:대화명
bw.write(ar[0] + "님이 퇴장하였습니다.\n");
bw.flush();
br.close();
bw.close();
socket.close();
System.exit(0);
}else if(ar[0].equals(Protocol.SEND_MESSAGE)) { //메세지 => 300:대화명:메세지
bw.write("[" + ar[1] + "]" + ar[2] + "\n");
bw.flush();
}
Protocol.java
package network;
public final class Protocol { // final이면 밑에 자식 안생김
public static final String ENTER = "100";
public static final String EXIT = "200";
public static final String SEND_MESSAGE = "300";
}
ProtocolServer.java
package network;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class ProtocolServer {
ServerSocket serverSocket;
Socket socket; //핸드폰이라 생각하기 //클라이언트와 통신할 소켓
BufferedReader br;
BufferedWriter bw;
public ProtocolServer() {
try {
serverSocket = new ServerSocket(9500); //9500번포트에서 클라이언트가 올 때까지 기다린다.
System.out.println("서버준비완료..");
//클라이언트와 연결을 수락한다.
socket = serverSocket.accept(); //클라이언트를 낚아채서 클라이언트와 대화할 소켓을 생성한다.
//클라이언트 들어오기 전까지는 멈춰있다.
- 서버 소켓을 생성하여 9500번 포트에서 클라이언트의 연결을 기다린다.
- 클라이언트의 연결을 수락하고 클라이언트와의 통신을 위한 소켓을 생성한다.
- 클라이언트가 연결될 때까지 이 부분에서 코드 실행이 멈춘다.
//IO생성
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
} catch (IOException e) {
System.out.println("클라이언트와 연결이 안되었습니다.");
e.printStackTrace();
System.exit(0);
}
- 클라이언트로부터 데이터를 읽기 위한 입력 스트림을 생성한다.
- 클라이언트로 데이터를 보내기 위한 출력 스트림을 생성한다.
String line;
try {
//클라이언트로부터 메시지 받아서 읽기
line = br.readLine();
//클라이언트로 보내기
String[] ar = line.split(":");
- 클라이언트로부터 한 줄의 데이터를 읽는다.
- 받은 데이터를 콜론(:)을 기준으로 분리한다.
if(ar[0].equals(Protocol.ENTER)) {//입장 => 100:대화명
bw.write(ar[0] + "님이 입장하였습니다.\n");
bw.flush();
}else if(ar[0].equals(Protocol.EXIT)) { //퇴장 => 200:대화명
bw.write(ar[0] + "님이 퇴장하였습니다.\n");
bw.flush();
br.close();
bw.close();
socket.close();
System.exit(0);
}else if(ar[0].equals(Protocol.SEND_MESSAGE)) { //메세지 => 300:대화명:메세지
bw.write("[" + ar[1] + "]" + ar[2] + "\n");
bw.flush();
}
}catch(IOException e) {
e.printStackTrace();
}
}//ProtocolServer()
- 프로토콜에따라 메시지를 처리한다.
public static void main(String[] args) {
new ProtocolServer();
}
}
서버준비완료..
ProtocolClient.java
package network;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class ProtocolClient {
Socket socket; //핸드폰이라 생각하기 //서버와 통신할 소켓
BufferedReader br;
BufferedWriter bw;
Scanner scan;
public ProtocolClient() {
try {
socket = new Socket("localhost", 9500); //서버에 연결한다.
- 서버에 연결하기 위해 클라이언트 소켓을 생성하고, localhost의 9500번 포트에 연결한다.
//IO생성
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
scan = new Scanner(System.in);
} catch (UnknownHostException e) {
System.out.println("서버를 찾을 수 없습니다.");
e.printStackTrace();
System.exit(0);
} catch (IOException e) {
System.out.println("서버와 연결이 안되었습니다.");
e.printStackTrace();
System.exit(0);
}
- 서버로부터 데이터를 읽기 위한 입력 스트림을 생성한다.
- 서버로 데이터를 보내기 위한 출력 스트림을 생성한다.
String message, line;
try {
while(true) { //상대가 전화 끊을 때까지 계속 하는 것처럼 무한루프
//서버로 보내기
System.out.println();
System.out.println("입장은 100:대화명 이라고 입력하세요");
System.out.println("퇴장은 200:대화명 이라고 입력하세요");
System.out.println("메세지는 300:대화명:메세지 이라고 입력하세요\n");
message = scan.nextLine();
bw.write(message + "\n"); //서버로부터 메시지 보내기
bw.flush(); //버퍼 비워주기 / 그래야 다음 데이터가 또 나갈 수 있다.
- 사용자로부터 메시지를 입력받는다.
- 입력받은 메시지를 서버로 보낸다.
- 버퍼를 비워 데이터를 전송한다.
//서버로부터 받기
line = br.readLine(); //서버로부터 메시지 받기
System.out.println(line);
- 서버로부터 한 줄의 데이터를 읽는다.
- 서버로부터 받은 메시지를 출력한다.
//200:apple -> "200", "apple"
String [] ar = message.split(":"); //:로 분리해라
//if(ar[0].equals("200")) {
if(ar[0].equals(Protocol.EXIT)) {
br.close();
bw.close();
socket.close();
System.exit(0);
}
}// while
} catch (IOException e) {
e.printStackTrace();
}
}// ProtocolClient()
- 메시지가 퇴장 메시지인지 확인하고, 퇴장 메시지인 경우 클라이언트를 종료한다.
public static void main(String[] args) {
new ProtocolClient();
}
}
입장은 100:대화명 이라고 입력하세요
퇴장은 200:대화명 이라고 입력하세요
메세지는 300:대화명:메세지 이라고 입력하세요
입장은 100:대화명 이라고 입력하세요
퇴장은 200:대화명 이라고 입력하세요
메세지는 300:대화명:메세지 이라고 입력하세요
100:수민
수민님이 입장하였습니다.
입장은 100:대화명 이라고 입력하세요
퇴장은 200:대화명 이라고 입력하세요
메세지는 300:대화명:메세지 이라고 입력하세요
300:수민:안녕
[수민]안녕
입장은 100:대화명 이라고 입력하세요
퇴장은 200:대화명 이라고 입력하세요
메세지는 300:대화명:메세지 이라고 입력하세요
200:나가라 얍
나가라 얍님이 퇴장하였습니다.
[서버]
- 서버 소켓을 생성하여 클라이언트 연결을 기다린다.
- 클라이언트가 연결되면 소켓을 통해 데이터를 주고받는다.
- 프로토콜에 따라 입장, 퇴장, 메시지 전송을 처리한다.
- 클라이언트가 퇴장하면 서버도 종료된다.
[클라이언트]
- 서버에 연결하고 입출력 스트림을 생성한다.
- 사용자가 입력한 메시지를 서버로 보내고 서버로부터 메시지를 받는다.
- 퇴장 메시지를 입력하면 클라이언트도 종료된다.
'JAVA' 카테고리의 다른 글
DAY 16 - LOMBOK / 시퀀스 객체 / JDBC / DB 연결 (2024.07.24) (0) | 2024.08.09 |
---|---|
DAY 17 - MEMBER (2024.07.25) (0) | 2024.08.08 |
DAY 19 - Lambda (2024.07.29) (0) | 2024.08.07 |
DAY 21 - Network Thread (2024.07.31) (0) | 2024.08.06 |
DAY 21 - Stream (2024.07.31) (0) | 2024.08.06 |