네트워크

류정훈·2023년 1월 3일
0

학습내용

목록 보기
12/15

네트워크

서버 : 서비스를 제공하는 프로그램 또는 컴퓨터
클라이언트 : 서비스를 요청하여 사용하는 프로그램 또는 컴퓨터

  • 서버와 클라이언트
    네트워크로 연결된 컴퓨터간의 관계를 역할(role)로 구분한 개념
    서버는 서비스를 제공하는 프로그램으로 클라이언트의 연결을 수락하고
    요청 내용을 처리 후 응답을 보내는 역할
    클라이언트는 서비스를 받는 프로그램으로 네트워크 데이터를 필요로 하는 모든 어플리케이션이 해당 됨
  • IP주소
    네트워크 상에서 컴퓨터를 식별하는 번호로 네트워크 어댑터(랜카드)마다 할당 되어 있음
  • 포트(Port)
    같은 컴퓨터 내에서 프로그램을 식별하는 번호로
    클라이언트는 서버 연결 요청 시 IP주소와 포트 번호를 알아야 함

소켓 프로그래밍

  • TCP(Transmission Control Protocol)
    데이터의 전달의 신뢰성을 최대한 보장하기 위한 방식으로 연결지향형 통신이다.
    순차적으로 데이터를 전송하고 확인 및 오류 시 재전송을 한다.
  • UDP(User Datagram Protocol)
    데이터의 빠른 전달을 보장하기위한 방식으로 비연결 지향형 통신이다.
    확인 및 재전송 작업이 없다.

TCP 소켓 프로그래밍

서버 클래스

public void serverStart() {
		//1. 서버의 포트번호 정함
		int port = 8500; // port 번호는 0~65535사이 지정 가능
						// 단, 1023번 이하는 이미 사용중인 경우가 많으니 제외
		
		/*사용할 변수를 미리 선언 */
		ServerSocket serverSocket = null; // 서버소켓 저장용 변수
		Socket clientSocket = null; // 클라이언트 소켓 저장 변수
		
		InputStream is = null; //클라이언트 -> 서버입력용 스트림 변수
		BufferedReader br = null; // 입력용 보조 스트림 변수
		
		
		OutputStream os = null; // 서버 -> 클라이언트 출력용 스트림 변수
		PrintWriter pw = null; // 출력용 보조 스트림 변수
		
		//BufferedWriter br = null;
		// printWriter에는 print println printf 등 다양한 출력함수를 제공함으로서 파일출력을 편하게 해줌
		
		try {
			//2. 서버용 소켓 객체 생성
			serverSocket = new ServerSocket(port); // 서버용 소켓을 생성하여 포트 결합
			
			//3. 클라이언트 쪽에서 접속 요청이 오길 기다림
			// - 서버용 소켓은 생성되면 클라이언트 요청이 오기전까지
			// 다음 코드를 수행하지 않고 대기하고 있음
			System.out.println("[Server]");
			System.out.println("클라이언트 요청을 기다리고 있습니다....");
			
			//4. 접속 요청이 오면 요청 수락 후 해당 클라이언트에 대한 소켓 객체 생성
			// -> 요청을 수락하면 자동으로 socket객체가 얻어와짐
			clientSocket = serverSocket.accept();
			
			//접속하 클라이언트의 ip를 얻어와 출력
			String clientIP = clientSocket.getInetAddress().getHostAddress();
			// ip주소 형태 만들기
			
			System.out.println(clientIP + "가 연결을 요청함...");
			//5. 연결된 클라이언트와 입출력 스트림 생성
			is = clientSocket.getInputStream(); // clientsocket에서 제공하는 스트림
			os = clientSocket.getOutputStream(); // clientsocket에서 제공하는 스트림
			
			
			//6. 보조 스트림을 통해 성능 개선
			br = new BufferedReader(new InputStreamReader(is) );
			//InputStreamReader : 바이트 기반 스트림과 문자기반 스트림 연결에 사용하는 스트림
			pw = new PrintWriter(os); // 얘는 따로 필요없음
			//7. 스트림을 통해 읽고 쓰기
			pw.println("[서버 접속 성공]");
			pw.flush(); // 스트림에 있는 내용을 모두 밀어냄
			// close()도 밀어내는게 가능한데 굳이 flush를 사용하는 이유
			// ==> 스트림을 닫지 않은 상태에서 내용을 내보내고 싶은 경우가 있음
			
			// 7-2) 클라이언트 -> 서버에서 입력(메세지 전송 받기)
			String message = br.readLine(); //클라이언트 메세지를 한 줄 읽어옴
			System.out.println(clientIP + "가 보낸 메세지 : " + message);
			
			
		}catch(IOException e) {
			e.printStackTrace();
		}finally {
			//8. 통신 종료
			// 사용한 스트림, 소켓 자원을 모두 반환(close)
			
			try {
				//보조스트림 close시 연결된 기반 스트림(is,os)도 같이 close됨
				if(pw != null) pw.close();
				if(br != null) br.close();
				
				if(serverSocket != null) serverSocket.close();
				if(clientSocket != null) clientSocket.close();
			}catch(IOException e ) {
				e.printStackTrace();
			}
		}
	}
}

클라이언트 클래스

public class TCPClient {
	public void clientStart() {
		//1.서버의 IP주소와 서버가 정한 포트번호를 매개변수로 하여 클라이언트용 소켓 객체 생성
		int port = 8500;
		String serverIP = "127.0.0.1"; // loop back ip(내 컴퓨터를 가리키는 ip)
		
		/*필요한 변수 선언*/
		Socket clientSocket = null; // 서버와 연결할 클라이언트용 소켓을 저장할 변수
		BufferedReader br = null; // 서버 -> 클라이언트로 읽어오는 보조스트림
		PrintWriter pw = null; // 클라이언트 -> 서버로 출력하는 보조 스트림
		
		try {
		//2.서버와의 입출력 스트림 오픈 -> 먼저 소켓이 필요함
		System.out.println("[Client]");	// 클라이언트임을 나타냄
		clientSocket = new Socket(serverIP, port); //클라이언트에서 만들어진 소켓을 서버에서 얻어감
		
		//3.보조 스트림을 통해 성능 개선
		br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
		pw = new PrintWriter(clientSocket.getOutputStream());
		
		//4.스트림을 통해 읽고 쓰기
		//4-1) 서버 접속 성공 시
		// 서버가 출력한"[서버 접속 성공]" 메세지 읽어오기
		String message = br.readLine();
		System.out.println("서버로부터 받은 메세지 : " + message);
		
		// 4-2) 클라이언트 -> 서버로 메세지 전송
		Scanner sc = new Scanner(System.in);
		System.out.print("입력 : ");
		String input = sc.nextLine();
		
		pw.println(input); //쓰기
		pw.flush(); //밀어넣기
		
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			//5.통신 종료
			try {
				if(pw != null)pw.close();
				if(br != null)br.close();
				if(clientSocket != null)clientSocket.close();
			}catch(IOException e) {
				e.printStackTrace();
			}
		}
	}
}

profile
It works...why?

0개의 댓글