JAVA/JAVA수업

#17. Map, Network

열하나요 2023. 7. 25. 15:32
public class ClientProgram {
	public static void main(String[] args) {
    	Scanner sc = new Scanner(System.in);
        
        Socket socket = null;
        BufferedReader br = null;
        PrintWriter pw = null;
        
        String serverIp = "127.0.0.1";
        int port = 5555;
        
        try {
        	socket = new Socket(serverIp, port);
            if(socket != null) {
            	System.out.println("서버와 연결 성공 ~");
                
                br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                pw = new PrintWrite(socket.getOutputStream());
                
                while(true) {
                	System.out.print("서버에게 보낼 내용(exit입력하면 종료!) : ");
                    String sendMessage = sc.nextLine();
                    if(sendMessage.equals("exit")) break;
                    
                    pw.println(sendMessage);
                    pw.flush();
                    
                    String message = br.readLine();
                    System.out.println("서버로부터 전달받은 메시지 : " + message);
                }
        } catch (IOException e) {
        	e.printStackTrace();
        } finally {
        	try {
            	pw.close();
                br.close();
                socket.close();
            } catch (IOException e) {
            	e.printStackTrace();
            }
        }
    }
}

17-1. Map

먼저 Curry 클래스를 만들어주면, 두개의 필드에 대한 생성자 및 getter/setter, 오버라이딩을 해준다. (생략)

public class Curry {
	
	private String topping;
	private int spicy;

#HashMap 

public class HashMapRun {
	public static void main(String[] args) {
    	HashMap<String, Curry> map = new HashMap();
		map.put("새우카레", new Curry("새우", 1));
		map.put("치킨카레", new Curry("치킨", 2));
		map.put("카츠카레", new Curry("돈까스", 3));
        
        System.out.println(map.get("카츠카레"));
		Curry carre = /*(Curry)*/map.get("버터치킨카레");

.put() : 요소 추가

.get(Object key) : Object  (key는 식별자개념!!!!!! => key를 가지고 value를 찾는다.)

.size() : Map에 담겨있는 요소의 개수

.replace(K key, V value) : 해당 키 값을 찾아서 밸류값을 변경시켜줌

.remove(Object key) : 해당 키 값을 찾아서 => 키 + 밸류 세트로 지워주는 메소드

 

원래 Hashmap에 get을 하면 Object여서 다운캐스팅 했어야 하지만

제네릭 설정을 해놨기 때문에 keyType == String / returnType == Curry가 되기 때문에 안해도 된다 (List는 다운캐스팅 했어야 했다.)

 

HashMap에 들어있는 모든 요소들에 순차적으로 접근하고자 한다면..?

방법 1. Map이 가지고 있는 Key값을 Set계열로 바꿔서 => Iterator를 사용할 것

    Set<String> keyset = map.keySet();
    Iterator<String> itKey = keyset.iterator();
    
    while(itKey.hasNext()) {
        String key = itKey.next();
        System.out.println(key + " - " + map.get(key));
    }

방법 2. entrySet() 이용하는 방법

    Set<Entry<String, Curry>> entrySet = map.entrySet();

    for(Entry<String, Curry> e : entrySet) {
        System.out.println(e.getKey() + " - " + e.getValue());
    }

 

#Properties

key와 value를 모두 String으로 다룬다!!!!!!!!!!!!!!!!!!!!

Properties의 용도 => 파일 입/출력하기 위해 쓴다.

자주 변경되지 않은 설정정보, 해당 프로그램이 기본적으로 가져야 할 정보들을 담는 파일

 

public class PropertiesRun {
	public static void main(String[] args) {
		Properties prop = new Properties();
		prop.setProperty("List", "ArrayList");
		prop.setProperty("Set", "HashSet");
		prop.setProperty("Map", "HashMap");
		
        try {
        	prop.store(new FileOutputStream("test.properties"), "Test...");
        } catch (IOException e) {
        	e.printStackTrace();
        }
    }
}

prop.store(OutputStream os, String comments); : 파일을 기록할 때 사용하는 메소드

load(InputStream is) : 파일로부터 읽어올 때 사용하는 메소드

 

 

17-2. Network

네트워크(Network)
통신 가능한 두 대 이상의 장치들을 물리적 또는 논리적으로 연결한 상태
네트워크를 통해 데이터 교환이 가능해짐

MAC(Media Access Control) 주소와 IP(Internet Protocol)주소와 Port번호
- MAC Address : NIX(Network Interface Card)에 실제 제조시 붙여지는 물리적인 주소
- IP Address : Internet상 각 Host들을 식별해줄 수 있는 논리적인 주소
- Port Number : Host 내부에서 작동하는 Process를 식별할 때 각각의 Process를 식별해주는 내부 번호
 => IP주소와 Port번호는 항상 고정값이 아니라 변동이 가능한 유동적인 값이다.
단. 값을 바꿀 때 IP주소같은 경우는 현재 같은 네트워크 범위 안에서, Port번호는 컴퓨터 내부에서 중복이 발생하면 안됨!!! 충돌이 일어남!!

- Server와 Client
- 서버 ; Client(고객)에게 서비스를 제공해주는 물리적인 컴퓨터 또는 프로그램
즉, Client의 요청에 대한 응답을 해주는 서비스 제공자
- 클라이언트 : Server에게 서비스를 요청하는 컴퓨터 또는 프로그램
즉, 서비스를 제공받는 고객
=> 클라이언트 입장에서는 서버에 요청하기 위해서 요청하고자하는 서버의 IP주소와 Port번호를 알아야 함
=> 서버는 자기 혼자서 응답을 보낼 수 없음! 클라이언트의 요청이 들어와야만 응답을 보낼 수 있는 구조

InetAddress : 네트워크 정보를 확인할 수 있는 클래스

public static void main(String[] args) {
	try {
    	InetAddress localhost = InetAddress.getLocalHost();
        System.out.println(localhost.getHostName());
        System.out.println(localhost.getHostAddress());
        
        InetAddress googleHost = InetAddress.getByName("www.google.com");
        System.out.println(googleHost.getHostName());
        System.out.println(googleHost.getHostAddress());
        
        InetAddress[] naverHost = InetAddress.getAllByName("www.naver.com");
        System.out.println("네이버 호스트 개수 : " + naverHost.length);
        for(InetAddress n : naverHost) {
        	System.out.println(n.getHostName());
            System.out.println(n.getHostAddress());
        }
    } catch (UnknownHostException e) {
    	e.printStackTrace();
    }
}

localhost => 내 PC를 지칭 => 127.0.0.1

 

.getLocalHost() : 작업하고 있는 Host의 정보를 반환해주는 메소드

.getHostName() : 내 PC이름

.getHostAddress() : 내 IP주소

.getByName("www.google.com") : 도메인 이름이라는 고유한 이름을 통해 해당 서버의 정보를 얻어내서 반환

.getAllByName("www.naver.com") : 해당 서버의 모든 정보를 얻어내서 반환

.length : 호스트 개수

 

현재 구동중인 서버가 있다면 클라이언트는 언제든 서버로 요청을 보낼 수 있음
=> 항상 응답결과가 돌아옴!
Client - Server모델에서 프로그램 동작 방식
"요청(request)"과 "응답(response)"에 의해서 프로그램이 돌아감("통신"한다라고 표현)
웹에서의 통신 방식 : HTTP 통신(HTTPS : 보안관련된 내용이 추가)

순수 자바만을 가지고 서버와 클라이언트 간의 간단한 통신 해보기
=> 이 때 데이터를 입/출력하고자 한다면 서버와 클라이언트 사이에 스트림(연결 통로)가 필요함

소켓(Socket) 
Process(실행중인 프로그램)간의 통신을 담당함

(TCP/UDP)
TCP 방식 : 데이터 전송속도는 느리나, 데이터를 정확하고 안정적으로 전달하는 방식
=> 주로 신뢰성이 요구되는 프로그램에서 사용(웹, 이메일, 파일전송)
UDP 방식 : 데이터 전송속도는 빠르나, 신뢰성이 없는 데이터가 전송될 수 있음
=> 주로 데이터를 빠른 속도로 전송하고자하는 프로그램(OTT 등)

 

 

TCP

서버 측

public class ServerProgram {
	public static void main(String[] args) {
    	Scanner sc = new Scanner(System.in);
        
        ServerSocket server = null;
        BufferedReader br = null;
        PrintWriter pw = null;
        
        int port = 5555;
        try {
        	server = new ServerSocket(port);
            Socket socket = server.accept();
            System.out.println(socket.getInetAddress().getHostAddress() + "가 연결을 요청함");
            
            br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            pw = new PrintWriter(socket.getOutputStream());
            
            while(true) {
            	String message = br.readLine();
                System.out.println("클라이언트로부터 받은 메시지 : " + message);
                
                System.out.print("클라이언트에게 보낼 내용 : ";
                String sendMessage = sc.nextLine();
                pw.println(sendMessage);
                
                pw.flush();
            }
        } catch (IOException e) {
        	e.printStackTrace();
        } finally {
        	try {
            	pw.close();
                br.close();
                server.close();
            } catch (IOException e) {
            	e.printStackTrace();
            }
        }
    }
}

클라이언트 측

 

'JAVA > JAVA수업' 카테고리의 다른 글

#16. Test2 / 과제  (0) 2023.07.24
#15. Set  (0) 2023.07.21
#14. I.O(Writer/Reader), buffer, Collection, List  (0) 2023.07.20
#13. API, I.O(Input/Output)  (0) 2023.07.19
#12. 추상클래스, 인터페이스, 예외처리  (0) 2023.07.18