네트워크

제이·2023년 3월 20일
1

네트워크

목록 보기
1/2

네트워크란?

네트워크란? 통신이 가능한 디바이스끼리 통신하는 거 예) 인터넷

ip란?

수많은 컴퓨터들 중에서 딱 하나를 어떻게 찾았을까? ip로 찾는다.
ip : internet protocol(인터넷 프로토콜) = 디바이스 식별자.
장비를 통한 식별을 ip를 통해서 한다.

port란?

장비를 찾았다고 해서 끝이 아니라, 디바이스에 동작하는 여러가지 프로세스 중에서 또 누군지를 찾아내야 한다. 어떤 프로그램과 통신 할거냐.
-> 이걸 식별하는 게 'port'다.= 프로세스 식별자
어느 서버에 접속해야 하는지 컴퓨터에게 알려주어야 한다. 이때 사용되는 것이 포트 번호이다.
o/s가 할당해준다.

택배) 주소 : ip , 받는 사람 : port
port : 보통은 10000번 정도라고 생각.
이 안에 있는 것들은 약속이 되어있다.

ip : 컴퓨터에 접속하는 주소.
port : 컴퓨터 안에 설치된 서버에 접속하는 주소.

프로토콜이란?

프로토콜 : 클라이언트와 서버와의 통신규약
(범위안에서만 요청하고 응답.)
대표적인 인터넷 표준 프로토콜에는 TCP와 UDP가 있다.

서로 다른 두 객체가 주고 받는 걸 통신이라고 볼 수 있다.
통신 프로토콜 :
예를 들어 중국집에서 짜장면 달라고 요청 (O).
중국집에서 아메 하나 주세요(X) - 요청의 범위를 벗어난 거.

프로토콜을 설계하는 게 네트워크를 설정하는 것 중에 제일 처음 하는 거.
예시 ) http 프로토콜 이름이다. ftp(파일 주고 받을 때 쓰는 거.)

프로토콜이 정해진다는 것은 어떻게 보내고, 어떻게 받을 수 있는 지 정해진다는 것.

w3c, Ieee 가 저런 걸 만들어 낸다.

기술의 규격을 딱 정의해놓음으로 인해서, 오용,남용을 막을 수 있고, 서로 독립된 작업을 할 수 있게 해준다.


naver.com(전세계 고정값)이라고 치면 DNS(도메인 네이밍 서버)로 간다.
DNS가 ip를 던져준다. 그리고 전달된 ip로 접속한다.

결국에 갈때는 ip로 가는데, 왜 저렇게 해놨을까?
굳이 번거롭게 DNS를 거쳐서 하면 어떤 문제를 해결할 수 있었을까?
다이렉트로 ip로 접근한다면 - 네이버 ip가 바뀌면 어떻게 될까?

  • 서버입장에서 ip가 바뀐다는 것을 알려줄 수 없음.
    쓰는 사람은 바뀐 줄도 모른다.
    그래서 DNS를 통해서 해놓으면 쓰는 사람은 그냥 편하게 사용할 수 있다.

포트번호는 ip뒤에 ':80(아무말 안하면 80으로 고정)' 이런식으로 붙는다.
naver.com : 80.

프로토콜 ://URL (? query) -> ()안에 들어가는게 파라미터 같은 거.
"http:" "//" host [":" port]abs_paath["?" query]] - 이렇게 생김.


TCP 와 UDP
TCP : 연결형 통신방식, 인터넷, 신뢰성있는데이터보장 - 전화(받는 상대가 반드시 있어야 한다.) - 우리가 만든 방식!
UDP : 비연결형 통신방식, 신뢰성보장하지 않는다, 빠르다 - 편지(내가 보냈지만 받았는지 아닌지 모른다)받든지말든지 신경안쓰고 걍 보내는 거. 서버와 클라이언트의 역할이 약간 모호하고 불투명. 내가 서버일수도있고 클라이언트일수도 잇고.. 그런 느낌.

InetAddress - ip를 나타내는 객체

public class NSLookup {
	public static void main(String[] args) {
		String domain = JOptionPane.showInputDialog("도메인을 입력하시오");
		
		InetAddress inetaddr[] = null;
		
		try {
			inetaddr = InetAddress.getAllByName(domain);
		}catch(UnknownHostException e) {
			e.printStackTrace();
		}
		for(int i = 0 ; i < inetaddr.length ; i++) {
			System.out.println(inetaddr[i].getHostName());
			System.out.println(inetaddr[i].getHostAddress());
			System.out.println(inetaddr[i].toString());
			System.out.println("---------------------");
		}
	}
}
//결과
naver.com	//hostname
223.130.200.107	//hostAddress
naver.com/223.130.200.107	//toString()
---------------------
naver.com
223.130.200.104
naver.com/223.130.200.104
---------------------
naver.com
223.130.195.95
naver.com/223.130.195.95
---------------------
naver.com
223.130.195.200
naver.com/223.130.195.200
---------------------

도메인 하나당 할당된 ip가 하나가 아니기 때문에 여러가지가 뜨고, 그래서 배열을 이용한다. -> 도메인 하나에 ip는 여러개.

getAllByName() : 도메인명에 지정된 모든 ip주소를 배열에 담아서 반환합니다

네트워크

프로그램이 두개이다.(서버와 클라이언트)
클라이언트 : 요청하는 거, 서버 : 요청받는 거

public class EchoServer {
	public static void main(String[] args) {
		Socket sock = null;
		
		OutputStream out = null;
		OutputStreamWriter osw = null;
		PrintWriter pw = null;
		
		InputStream in = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		
		try {
			ServerSocket server = new ServerSocket(10001);//파라미터는 포터번호. 
			System.out.println("접속을 기다립니다.");// 이거 하고 blocked 된다.
            
			//client 정보가 담긴 소켓
			sock = server.accept();	
            //이 accept()가 클라이언트의 접속을 받아주는 메소드.
			
			InetAddress inetaddr = sock.getInetAddress();	// 아이피 주소.
			
			System.out.println(
            inetaddr.getHostAddress() + "로부터 접속하였습니다."); 
			out = sock.getOutputStream();	
            //소켓에 쓸 수 있는 outputstream 소켓에 write하면 클라인언트한테 간다.
			
            in = sock.getInputStream();
            // 클라이언트가 보낸 걸 읽어낼 수 있는 스트림.
			
			osw = new OutputStreamWriter(out);
			
           ⭐⭐ pw = new PrintWriter(osw);
            //줄단위로 보내기. 결국  ⭐⭐를 읽는다. 
			
			isr = new InputStreamReader(in);
			⭐⭐br = new BufferedReader(isr);
            //줄단위로 읽기.
            
			String line = null;
			while((line = br.readLine()) != null) {	
            // 소켓으로부터 읽어낸 소켓으로 읽는거. 
            //자력탈출 불가능. 클라이언트가 보낼때까지 대기.
            
				System.out.println(
                "클라이언트로 부터 전송받은 문자열 : " + line);
				pw.println(line);	
                //소켓으로 뽑아낸 아웃풋 보낸내용을 다시 클라이언트에게 보낸다.
                //받으면 콘솔에 찍고 다시 대기.
				pw.flush();
			}
           //while문 계속 반복.
             
			System.out.println(line);
		}catch(Exception e) {
			System.out.println(e);
		}finally {
			try  {
				br.close();
			}catch(Exception e) {}
			try  {
				isr.close();
			}catch(Exception e) {}
			try  {
				in.close();
			}catch(Exception e) {}
			try  {
				pw.close();
			}catch(Exception e) {}
			try  {
				osw.close();
			}catch(Exception e) {}
			try  {
				out.close();
			}catch(Exception e) {}
			try  {
				sock.close();
			}catch(Exception e) {}
		}
	}
}
 -------------------------------------------------------------
 public class EchoClient {
	public static void main(String[] args) {
		Socket sock = null;
		
		OutputStream out = null;
		OutputStreamWriter osw = null;
		PrintWriter pw = null;
		
		InputStream in = null;
		InputStreamReader isr = null;
		BufferedReader br = null;
		
		BufferedReader keyboard = null;
		InputStreamReader keyIsr = null;
		try {
			//소켓이 생성 : 접속이 되었다라는 뜻
			//server정보
			sock = new Socket("127.0.0.1", 10001);
            //소켓이 만들어 졌다는 것이 접속을 했다는 것. 
			
			⭐⭐keyIsr = new InputStreamReader(System.in);
            //서버보다 이게 하나 더 있다. 키보드입력을 읽어들이는 스트림
            keyboard = new BufferedReader(keyIsr);
			
			out = sock.getOutputStream();
			in = sock.getInputStream();
			osw = new OutputStreamWriter(out);
			
            ⭐⭐pw = new PrintWriter(osw);	
            //서버한테 write할 수 있는 스트림
			
			isr = new InputStreamReader(in);
			⭐⭐br = new BufferedReader(isr);	
			
			String line = null;
			
			//키보드 대기
			while((line = keyboard.readLine())!=null) {	
            // 읽을 게 생길때까지 멈춘다. 
			//우리가 입력하면 풀 수 있다. 
				
				if(line.equals("quit")) {
					break;
				}
				pw.println(line);	//서버한테 write. 
				pw.flush();
				
				//서버로부터 전송대기
				String echo = br.readLine();
                // 여기서 또 멈춘다. 
				
                System.out.println("서버로부터 전달받은 문자열 : " + echo);
                //화면에 찍고 이 다음에 키보드 입력 대기.
			}
            //while문 계속 반복.
            
			pw.close();
			br.close();
			sock.close();	// 잘못 쓴 거임. close() 한번만 해주면 되는 듯
		}catch(Exception e) {
			System.out.println(e);
		}finally {
			try { 
				keyboard.close();
			}catch(Exception e) {}
			try {
				keyIsr.close();
			}catch(Exception e) {}
			try {
				br.close();
			}catch(Exception e) {}
			try {
				isr.close();
			}catch(Exception e) {}
			try {
				in.close();
			}catch(Exception e) {}
			try {
				pw.close();
			}catch(Exception e) {}
			try {
				osw.close();
			}catch(Exception e) {}
			try {
				out.close();
			}catch(Exception e) {}
			try {
				sock.close();
			}catch(Exception e) {}
			
		}
	} //main
}

결과창
왼쪽이 client, 오른쪽이 server
결과창을 보면, client가 키보드에 적은 것이 출력되고 server를 통해서 한번 더 출력된다.
그리고 클라이언트에 quit를 적으면 서버에서 null값으로 마무리된다.


위의 코드는 클라이언트와 서버가 주고 받기 위한 것. 클라이언트가 키보드에 입력한 것을 소켓을 통해 서버가 읽어들이고 그것을 다시 클라이언트에게 보여주기 위해 출력해서 다시 클라이언트가 읽어들이는 과정.
내가 "hello"를 치면 그걸 소켓을 통해서 서버로 가서 그 다음에 다시 읽어 들어와서 나의 콘솔창에 "hello"가 보인다.

서버와 클라이언트(코드 설명)

서버의 순서(?)

  • 1.serverSocket생성 : 서버소켓을 가지고 클라이언트의 소켓 접속을 기다림. - 하는 일 : 접속할 수 있겠끔 해주는 거. 접속을 했을 때, 클라이언트 소켓을 구해다 주는 역할. 서버는 수동적. 기다려야 한다.
    2.accept()생성 : 연결요청이 올 때까지 기다림.
    3.연결 요청이 들어오면, 새로운 socket객체를 생성하여 클라이언트와 서버를 연결한다.
    4.Socket객체의 Stream객체(InputStream, OutputStream)를 이용하여 메시지를 주고 받는다. - OutputStream객체를 구성하여 전송
    접속한 Socket의 getOutputStream()메서드를 이용하여 구한다.
    5.사용이 완료된 소켓은 close()메서드를 이용하여 종료 처리한다.

서버

🔔🔔기억하기) serversocket은 accept()를 불러오기 위한 것일뿐이다. 실질적인 서버에서의 클라이언트소켓은 Socket이다.

서버는 ServerSocket클래스를 사용한다. 클라이언트는 Socket클래스를 사용한다.

  • ServerSocket : 서버프로그램에서 사용하는 소켓
  • ServerSocket server = new ServerSocket(10001);
    //파라미터는 포터번호. 하는 일 : 클라이언트가 접속을 할 수 있게 해준다. 연결해주는 거.
    //소켓을 먼저 준비해야 통신이 된다. 그래서 ServerSocket을 먼저 해야 한다.
  • server.accept(); : 이 accept()가 클라이언트의 접속을 받아주는 메소드.이게 호출되면 프로그램이 멈춘다. 누군가 나한테 접속할때까지 멈춘다. 그리고 클라이언트 간다. 클라이언트가 소켓만들면 이게 되는 것 같음. 여기의 소켓은 클라이언트를 나타내는 것.
    이 소켓한테 듣고 말하면 알아서 통신을 해준다.
    이거 하고 얻어지는 소켓은 클라이언트를 대신하는 거.

-getHostAddress() : 아이피주소를 String으로 내보내 주는 거.

  • ⭐⭐표시되는 것들이 줄단위로 읽고 쓰는거.

while(클라이언트가 전송할때까지) { : 서버는 여기서만 대기. 클라이언트가 서버로 전송할 때 얘가 풀림.
콘솔 출력
다시 그대로 클라이언트에게 전송 : 얘로 인해서 클라이언트가 풀림.
}

while((line = br.readLine()) != null) {	
//소켓으로부터 읽어낸 소켓으로 읽는거. 읽을 게 있을 때까지 여기서 block상태가 된다. 
//클라이언트가 나한테 뭔가를 보낼때까지 기다리는 거 자력탈출 불가능
	System.out.println("클라이언트로 부터 전송받은 문자열 : " + line);
	pw.println(line);	
    //소켓으로 뽑아낸 아웃풋 보낸내용을 다시 클라이언트에게 보낸다
    //받으면 콘솔에 찍고 다시 대기.
	pw.flush();
}

클라이언트의 순서(?)

1.소켓을 생성하여 서버에 연결을 요청
2.연결이 정상적으로 이뤄졌다면, 생성된 소켓 객체를 이용하여 스트림(Stream) 객체를 가져와서 서버와 메시지를 주고 받는다.
-메시지 받으려고 inputStream.
3.사용이 완료된 소켓을 close().

클라이언트

서버는 ServerSocket클래스를 사용한다. 클라이언트는 Socket클래스를 사용한다.

  • sock = new Socket("127.0.0.1", 10001)
    : 소켓이 생성 - 접속이 되었다라는 뜻
    : server정보
    : 127은 내부 ip이다. 나를 나타내는 가상의 ip.
    : 클라이언트가 자기가 자기에게 접속한 것. 본인이 본인에게 접속하는 거다.
    첫번째 파라미터(디바이스식별자) : 접속할 ip
    두번째 파라미터(서버식별자) : 접속할 port번호(server에서 설정한 값 들고옴)

💡소켓이 만들어 졌다는 것이 접속을 했다는 것. -> new 소켓하면 서버의 accept()가 풀린다.

  • 서버쪽에 얘기하고 싶으면 write하는 거고 , 서버가 하는 거 듣고 싶으면 read하는 거. 클라이언트 소켓은 서버를 나타내는 대상.

while(키보드입력이 있을때까지) { : 클라이언트 여기서 대기, 파라미터에서 얻어온 값을 서버로 전송
서버로부터 전송값이 있을때까지 대기 : 여기서 또 대기. 서버에서 전송하는 값으로 얘가 풀린다.
콘솔출력
}

//키보드 대기
while((line = keyboard.readLine())!=null) {	
// 읽을 게 생길때까지 멈춘다. 
//클라이언트는 여기서 접속하고 여기서 제일 먼저 멈춘다. 
//사용자가 키보드이용해서 입력할 때까지 기다리는 거 우리가 입력하면 풀 수 있다
	if(line.equals("quit")) {
		break;
	}
	pw.println(line);	//서버한테 write. 
	pw.flush();			
	//서버로부터 전송대기
	System.out.println("서버로부터 전달받은 문자열 : " + echo);
    //화면에 찍고 이 다음에 키보드 입력 대기.
}

소켓

소켓이 뭐냐? 전화기 같은 거. 상대방에게 전화를 한다. 정우한테 하고 싶은 말이 있으면 전화기한테 말한다. 전화기는 정우가 아닌데, 전화기를 정우인 것처럼 얘기한다. 그 역할을 해주는게 소켓객체.
클라이언트가 서버에게 전화를 건다. 전화 거는 걸 말하는 것을 write()한다고 한다. 듣는 건 read한다고 한다.

7계층의 일을 소켓이 대신 해준다.

웹하려고 네트워크를 하는 것이다.


-마지막 사진은 퍼온거.


아래는 걍 수업 중간중간의 설명.

  • sql
    MySQL - 표준에 가까운..?

네이버에 접속할 때 아무데서나 들어온다. 어디서 들어와도 똑같이 작동하게 하는 거. - 크로스 브라우징
예)크롬에서도 네이버 접속, 엣지에서 네이버접속


선형문서 - 아날로그
비선형문서 - 디지털


메서드 이름 : 무슨일을 하는 가를 알아야 한다.
파라미터 : 약간 키워드 같은 거.

profile
Hello :)

0개의 댓글