버글버글

Java 수업 기록 (26) Network 본문

java/java 수업 기록

Java 수업 기록 (26) Network

Bugle 2022. 8. 18. 00:00
반응형

▶ URL 

1. Uniform Resource Locator (정형화, 형태가 정해져 있다.)
2. 정형화된 자원의 경로
3. 웹 주소를 의미

* java.net.URL;
4. 구성

예시) https://search.naver.com/search.naver?where=nexearch&sm=top_hty&fbm=1&ie=utf8&query=%EB%82%A0%EC%94%A8

http:// 프로토콜://  
search.naver.com 호스트  
search.naver 서버경로  
?where=nexearch&sm=top_hty&fbm ?파라미터=값&파라미터=값 (=변수)
1) https  secure http, 하이퍼텍스트 전송 프로토콜(통신규약)
2) 호스트 서버주소
3) 서버경로  URL Mapping
4) 파라미터 서버로 전송하는 데이터

예시)

		try {
			String apiURL = "https://search.naver.com/search.naver?query=날씨";
			URL url = new URL(apiURL);
			
			// URL 확인
			System.out.println("프로토콜 : " + url.getProtocol());
			System.out.println("호스트 : " + url.getHost());
			System.out.println("파라미터 : " + url.getQuery());
			
		} catch(MalformedURLException e) {
			System.out.println("API 주소 오류");
		}

 

 

▶ HttpURLConnection Class 

1. 웹 접속을 담당하는 클래스

2. URL 클래스와 함께 사용

3. URLConnection 클래스의 자식 클래스

4. URL 클래스의 openConnection() 메소드를 호출해서 HttpURLConnection 클래스 타입으로 저장

HTTP 응답 코드
1. 200 정상
2. 40X 요청이 잘못됨(사용자 잘못)
3. 50X 서버 오류

예시)★★ 외워야 함

		try {
			
			String apiURL = "https://www.google.com";
			URL url = new URL(apiURL);
			
			HttpURLConnection con = (HttpURLConnection)url.openConnection();
			
			System.out.println("응답 코드 : " + con.getResponseCode());
			System.out.println("컨텐트 타입 : " + con.getContentType());
			// naver.com - UTF-8
			// google.com - ISO-8859-1
			System.out.println("요청 방식 : " + con.getRequestMethod());
			
			con.disconnect();	// 접속 해제(생략 가능)
			
		} catch (MalformedURLException e) {	// URL 클래스
			System.out.println("API 주소 오류");
		} catch (IOException e) {	// HttpURLConnection 클래스
			System.out.println("API 접속 오류");
		}

 

▶ HttpURLConnection과 스트림 

예시)

		try {
			String apiURL = "https://www.naver.com";
			URL url = new URL(apiURL);
			HttpURLConnection con = (HttpURLConnection)url.openConnection();
			
			// 바이트 입력 스트림
			InputStream in = con.getInputStream();
			
			// 문자 입력 스트림으로 변환
			InputStreamReader reader = new InputStreamReader(in);
			
			// 모두 읽어서 StringBuilder에 저장
			StringBuilder sb = new StringBuilder();
			char[] cbuf = new char[100]; 	// 100 글자씩 처리
			int readCnt = 0; // 실제로 읽은 글자 수
			
			while((readCnt = reader.read(cbuf)) != -1) {
				sb.append(cbuf, 0, readCnt);
				}
			
			// StringBuilder의 모든 내용을 c:\\storage\\naver.html 로 내보내기
			File file = new File("c:\\storage", "naver.html");
			FileWriter fw = new FileWriter(file);
			
			fw.write(sb.toString());
			
			fw.close();
			reader.close();
			con.disconnect();
			
			
		} catch (MalformedURLException e) {
			System.out.println("API 오류");
		} catch (IOException e) {
			System.out.println("aPI 접속 및 연결 오류");
		}

 

▶ 인코딩 / 디코딩 

1. 인코딩 : UTF-8 방식으로 암호화
2. 디코딩 : UTF-8 방식으로 복호화 (복원)
3. 원본데이터 -> 인코딩 -> 전송 -> 디코딩 -> 원본데이터

예시)

		try {
			
			// 원본데이터
			String str = "한글 english 12345 !@#$+";
			
			// 인코딩
			String encode = URLEncoder.encode(str, "UTF-8");
			System.out.println(encode);
			
			// 디코딩
			String decode = URLDecoder.decode(encode, StandardCharsets.UTF_8);
			System.out.println(decode);
	
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

요청 (어떤 데이터를 (처리) 달라고 요청하는 것)

클라이언트 > 서버

 

요청할 주소 : apiURL

요청 파라미터(서버로 보내줄 데이터)

   필수/선택

 

apitURL?파라미터=값&파라미터=값...

 

▶ API 

요청
1. Request
2. 클라이언트 -> 서버

파라미터
1. Parameter
2. 보내는 데이터(변수 개념)

응답
1. Response
2. 서버 -> 클라이언트

▶ SeverSocket 

1. 클라이언트와 통신할 때 사용하는 클래스

예시)

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerMain {

	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		
		try {
			
			// ServerSocket 생성
			serverSocket = new ServerSocket();
			
			// ServerSocket의 호스트/포트번호 설정
			serverSocket.bind(new InetSocketAddress("localhost", 9099));
			
			// 접속한 클라이언트 개수
			int clientCnt = 0;
			
			// 서버는 종료 없이 무한루프
			while(true) {
				
				System.out.println("[서버] 클라이언트 접속 기다리는 중");
				
				// 클라이언트 접속 및 카운팅
				Socket clientSocket = serverSocket.accept();
				clientCnt++;
				
				// 클라이언트에게 Welcome 메시지 전송
				// 바이트 출력 스트림 중에서 DataOutputStream은 writeUTF() 메소드를 이용해서
				// 한글을 깨짐 없이 보낼 수 있다.
				DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
				out.writeUTF("[서버] 게스트" + clientCnt + "님 환영합니다!");
				
				// 클라이언트가 보낸 메시지 확인
				// 클라이언트가 OutputStreamWriter의 write()로 보냈으므로
				// InputStreamReader의 read()로 확인
				InputStreamReader in = new InputStreamReader(clientSocket.getInputStream());
				char[] cbuf = new char[5];
				int readCnt = 0;
				StringBuilder sb = new StringBuilder();
				while((readCnt = in.read(cbuf)) != -1) {
					sb.append(cbuf, 0, readCnt);
				}
				System.out.println("[서버] 클라이언트가 보낸 메시지 : " + sb.toString());
				
				// 입출력 스트림 종료
				out.close();
				in.close();
				
				// 클라이언트 접속 종료
				clientSocket.close();
				
				// 접속한 클라이언트가 3명이면 무한루프 종료
				if(clientCnt == 3) {
					System.out.println("[서버] 서버가 종료되었습니다.");
					serverSocket.close();
					break;
				}
				
			}  // while(true)
			
		} catch(IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(serverSocket.isClosed() == false) {
					System.out.println("[서버] 서버가 종료되었습니다.");
					serverSocket.close();
				}
			} catch(IOException e) {
				e.printStackTrace();
			}
		}

	}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;

public class ClientMain {

	public static void main(String[] args) {
		
		Socket clientSocket = null;
		
		try {
			
			// Socket 생성
			clientSocket = new Socket();
			
			// 접속할 Server의 InetSocketAddress 생성
			InetSocketAddress address = new InetSocketAddress("localhost", 9090);
			
			// 서버에 접속
			clientSocket.connect(address);
			
			System.out.println("[클라이언트] 접속 성공");			
			
		} catch(IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if( clientSocket.isClosed() == false) {
					clientSocket.close();
					System.out.println("서버 중지");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

}

 

예시2)

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerMain {

	public static void main(String[] args) {
		
		ServerSocket serverSocket = null;
		
		try {
			
			// ServerSocket 생성
			serverSocket = new ServerSocket();
			
			// ServerSocket의 호스트/포트번호 설정
			serverSocket.bind(new InetSocketAddress("localhost", 9099));
			
			// 접속한 클라이언트 개수
			int clientCnt = 0;
			
			// 서버는 종료 없이 무한루프
			while(true) {
				
				System.out.println("[서버] 클라이언트 접속 기다리는 중");
				
				// 클라이언트 접속 및 카운팅
				Socket clientSocket = serverSocket.accept();
				clientCnt++;
				
				// 클라이언트에게 Welcome 메시지 전송
				// 바이트 출력 스트림 중에서 DataOutputStream은 writeUTF() 메소드를 이용해서
				// 한글을 깨짐 없이 보낼 수 있다.
				DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
				out.writeUTF("[서버] 게스트" + clientCnt + "님 환영합니다!");
				
				// 클라이언트가 보낸 메시지 확인
				// 클라이언트가 OutputStreamWriter의 write()로 보냈으므로
				// InputStreamReader의 read()로 확인
				InputStreamReader in = new InputStreamReader(clientSocket.getInputStream());
				char[] cbuf = new char[5];
				int readCnt = 0;
				StringBuilder sb = new StringBuilder();
				while((readCnt = in.read(cbuf)) != -1) {
					sb.append(cbuf, 0, readCnt);
				}
				System.out.println("[서버] 클라이언트가 보낸 메시지 : " + sb.toString());
				
				// 입출력 스트림 종료
				out.close();
				in.close();
				
				// 클라이언트 접속 종료
				clientSocket.close();
				
				// 접속한 클라이언트가 3명이면 무한루프 종료
				if(clientCnt == 3) {
					System.out.println("[서버] 서버가 종료되었습니다.");
					serverSocket.close();
					break;
				}
				
			}  // while(true)
			
		} catch(IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(serverSocket.isClosed() == false) {
					System.out.println("[서버] 서버가 종료되었습니다.");
					serverSocket.close();
				}
			} catch(IOException e) {
				e.printStackTrace();
			}
		}

	}

}
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;

public class ClientMain {

	public static void main(String[] args) {
		
		Socket clientSocket = null;
		
		try {
			
			// Socket 생성
			clientSocket = new Socket();
			
			// 서버 접속
			clientSocket.connect(new InetSocketAddress("localhost", 9099));
			
			// 서버에 접속되면 Welcome 메시지가 넘어옴
			// 서버가 DataOutputStream의 writeUTF()로 메시지를 전송하므로
			// 클라이언트는 DataInputStream의 readUTF()로 메시지를 받음
			DataInputStream in = new DataInputStream(clientSocket.getInputStream());
			String message = in.readUTF();
			System.out.println("[클라이언트] " + message);
			
			// Scanner 클래스를 이용해 입력 받은 데이터를 서버로 보내기
			Scanner sc = new Scanner(System.in);
			System.out.print("서버로 전송할 메시지 >>> ");
			String send = sc.nextLine();
			OutputStreamWriter out = new OutputStreamWriter(clientSocket.getOutputStream());
			out.write(send);

			// 입출력 스트림 종료
			out.close();
			in.close();
			sc.close();
			
		} catch(IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(clientSocket.isClosed() == false) {
					System.out.println("[클라이언트] 클라이언트가 종료되었습니다.");
					clientSocket.close();
				}
			} catch(IOException e) {
				e.printStackTrace();
			}
		}

	}

}
반응형