본문 바로가기
Study/Back

Sep.20.Wed.2023 Java 수업 18일차 Network / TCP & UDP / Server Socket

by Jobsoony 2023. 9. 20.
728x90
반응형
  • TCP와 UDP
    네트워크 통신 프로토콜 중 두 가지 주요한 프로토콜로 컴퓨터 간 데이터 통신을 가능하게 한다.
public class InetAddressMain {

	public static void main(String[] args) {
		InetAddressMain iam = new InetAddressMain();
		// iam.InetExam();
		iam.InetSample();	
	}
	
	public void InetExam() {
		try {
			// 호스트 이름 이용해서 객체 생성
			InetAddress address = InetAddress.getByName("www.google.com");
			
			// IP 주소 출력
			System.out.println("Hos Name : " + address.getHostName());
			System.out.println("IP Address : " + address.getHostAddress());
			
			// 현재 호스트의 InetAddress 객체 얻기 -> 내가 사용하는 컴퓨터의 InetAddress 객체 얻기
			InetAddress localHost = InetAddress.getLocalHost();
			System.out.println("Local Host Name : " + localHost.getHostName());
			System.out.println("Local IP Address : " + localHost.getHostAddress());
			
			InetAddress address1 = InetAddress.getByName("www.naver.com");
			System.out.println("Hos Name : " + address1.getHostName());
			System.out.println("IP Address : " + address1.getHostAddress());
			
			InetAddress address2 = InetAddress.getByName("www.daum.net");
			System.out.println("Hos Name : " + address2.getHostName());
			System.out.println("IP Address : " + address2.getHostAddress());
			
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void InetSample() {
		// 호스트 이름을 가져와서 객체 생성
		try {
			InetAddress address = InetAddress.getByName("www.google.com");
			
			// IP 주소를 byte 배열로 읽기
			// InetAddress 객체에서 IP 주소를 바이트 배열로 얻음
			// IP 주소를 byte 배열로 얻으면 각 바이트를 통해 IP 주소를 다룰 수 있다.
			byte[] ipAddress = address.getAddress();
			System.out.println("IP Address를 byte로 얻음"); // while이나 for문 사용 가능
			for(byte ip : ipAddress) {
				System.out.println(ip);
			}
			System.out.println();
			
			// 도메인 명에 지정된 모든 호스트의 IP 주소를 배열로 얻기
			InetAddress[] alladdress = InetAddress.getAllByName("www.google.com");
			System.out.println("구글에 지정된 모든 호스트의 아이피 주소를 배열로 얻음");
			for (InetAddress addr : alladdress) {
				System.out.println(addr.getHostAddress());
			}
			// 호스트 이름 얻기
			String hostName  = address.getHostName();
			System.out.println("Host Name : " + hostName);	
			
			// 지역 호스트의 IP 주소 얻기
			InetAddress localHost = InetAddress.getLocalHost();
			System.out.println("Local Host Address : " + localHost.getHostAddress());
			
			// 멀티 캐스트 주소 여부 확인
			boolean isMultiCast = address.isMulticastAddress();
			System.out.println("멀티 캐스트 주소입니까? " + isMultiCast);
			
			// 호스트 이름을 이용하여 InetAddress 객체 생성
			InetAddress name = InetAddress.getByName("www.daum.net");
			System.out.println("IP 주소 이름 : "  + name.getHostAddress());
			
			// 호스트의 완전한 이름 가져오기 (전체 도메인 이름)
			// 호스트의 정규화된 (FQDN) 도메인의 이름을 얻음
			// FQDN(Full Qualified Domain Name)
			String hostFullName = name.getCanonicalHostName();
			System.out.println("Full Name : " + hostFullName);
			
			// LoopBack 주소 여부 확인
			boolean isLoopBack = address.isLoopbackAddress();
			System.out.println("뤂백인가요? " + isLoopBack);
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
	}
}

 

  • TCP(Transmission Control Protocol)
    연결 지향적 프로토콜로 데이터를 보내거나 받을 때 먼저 연결을 설정하고 데이터 전송이 완료되면 연결을 종료한다.
    데이터 손실을 최소화하기 위해 데이터 전송 상태를 확인하고 재전송 및 순서 제어를 지원한다.
    신뢰성이 높다.
    스트림 지향 프로토콜이며 데이터를 연속된 스트림으로 전송한다.
    이메일 전송, 파일 다운로드, 웹 브라우징 등에 쓴다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient {
	public static void main(String[] args) {
		try {
			// 서버 주소와 포트 번호로 소켓 생성
			// 서버 주소와 포트 번호는 내가 연결하고자 하는 포트와 동일해야 함
			Socket socket = new Socket("localHost", 8080);
			
			PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
			BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			
			// 서버 되는지 테스트 메세지
			out.println("안녕 서버?");
			
			// 서버로부터 메세지 전달되는지 확인 테스트
			String response = in.readLine();
			System.out.println("서버 응답 : " + response);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

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

public class TCPServer {
	public static void main(String[] args) {
		try {
			ServerSocket serverSocket = new ServerSocket(8080);
			System.out.println("서버 대기 중!");
			
			// 만약 클라이언트와 연결하고 싶다면 클라이언트와 연결하는 코드 작성
			while(true) {
				// 클라이언트와 연결 대기하는 코드
				Socket client = serverSocket.accept();
				System.out.println("클라이언트와 연결되었습니다.");
				
				client.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

 

  • UDP(User Datagram Protocol)
    비연결 지향적 프로토콜로 연결 설정 없이 데이터를 전송하고 데이터가 손실될 수 있으며 순서가 바뀔 수 있다.
    데이터 패킷 단위로 전송되며, 각 패킷은 독립적이다.
    신뢰성은 낮다.
    실시간 스트리밍, 온라인 게임, DNS 조회 등에 쓰인다.

 

 

  • ServerSocket이란?
    주로 서버 측에서 소켓 통신을 구현할 때 사용되는 클래스이다.
    서버 측에서 클라이언트의 연결을 수락하고 데이터를 주고받을 수 있게 해 준다.
    서버를 구현하면 클라이언트가 서버에 연결할 수 있고, 서버는 클라이언트와 통신할 수 있다.

    메서드)                              
    ServerSocket sS = new ServerSocket(/* 숫자로 된 서버 포트 번호*/); // 지정된 포트 번호로 서버 소켓을 생성
    accept() : 클라이언트의 연결을 기다리고, 클라이언트가 연결되면 클라이언트와 통신할 수 있는 소켓을 반환한다.
    close() : 서버 소켓을 닫는다.

 

  • Socket이란?
    클라이언트 측에서 사용하고 Socket 객체를 생성해 서버에 연결한다.
    서버 IP 주소와 포트 번호를 사용하여 특정 서버에 연결하는 역할을 한다.
    클라이언트와 서버 간의 데이터 통신을 가능하게 한다.

    메서드)
    getInputStream() : 입력 스트림을 얻을 때 사용
    getOutputStream() : 출력 스트림을 얻을 때 사용
    connect() : 클라이언트가 서버에 연결할 때 사용하고 주어진 서버 주소와 포트 번호로 서버에 연결을 시도
    close() : Socket에 객체를 받을 때 사용
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerMain {

	public static void main(String[] args) throws IOException {
		// 소켓 서버 생성
		ServerSocket serverSocket = new ServerSocket(1004); // ServerSocket import -> throw
		System.out.println("서버가 시작되었습니다.");
		
		// 클라이언트 연결 대기
		Socket clientSocket = serverSocket.accept(); // Socket import
		System.out.println("클라이언트가 연결되었습니다.");
		
		// 클라이언트로부터 데이터를 받기 위해 입력 스트림 생성
		BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));// BufferedReader import -> InputStreamReader import
		
		// 클라이언트로부터 데이터를 보내기 위한 출력 스트림 생성
		PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); // PrintWriter import
		String clientMsg;
		while((clientMsg = in.readLine()) != null) {
			System.out.println("클라이언트의 대화 : " + clientMsg);
			
			// 클라이언트에게 응답 전송
			out.print("서버의 응답 전송 : " + clientMsg);
		}
		
		// 클라이언트와의 연결 종료
		clientSocket.close();
		serverSocket.close();
	}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class ClientMain {
	public static void main(String[] args) throws UnknownHostException, IOException {
		// 서버에 연결하기 위한 소켓을 생성한다
		Socket socket = new Socket("localhost", 1004); // Socket import & throw
		
		// 서버로 데이터를 보내기 위한 출력 스트림 생성
		PrintWriter out = new PrintWriter(socket.getOutputStream(),true); // PrintWriter import
		
		// 서버로부터 데이터를 받기 위한 출력 스트림 생성
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));// BufferedReader & InputStreamReader import
		
		// 키보드로부터 입력 받기 위한 생성
		BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
		
		String userInputString;
		while((userInputString = userInput.readLine()) != null) {
			// 사용자 입력을 서버로 전송하겠습니다
			out.println(userInputString);
			
			// 서버로부터 받은 응답 출력
			String serverResponse = in.readLine();
			System.out.println("서버 너의 응답은 : " + serverResponse);
		}
		// 소켓 및 입력 스트림 닫기
		socket.close();
		userInput.close();
	}
}
728x90
반응형