InetAddress 클래스 : 네트워크 식별자(IP 주소 및 호스트이름)를 저장하기 위한 클래스
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAdressApp {
public static void main(String[] args) throws UnknownHostException {
InetAddress myComputer = InetAddress.getLocalHost();
System.out.println("myComputer = " + myComputer);
System.out.println("myComputer = " + myComputer.getHostName());
System.out.println("myComputer = " + myComputer.getHostAddress());
}
}
- InetAddress.getLocalHost() : 현재 사용중인 컴퓨터의 네트워크 식별자가 저장된 InetAddress 객체를 반환하는 메소드
- → UnknownHostException 발생(일반예외) : 호스트이름의 컴퓨터를 검색할 수 없는 경우 발생되는 예외
- 현재 사용중인 컴퓨터는 기본적으로 [127.0.0.1]의 IP 주소가 제공되며 [localhost]라는 이름으로 호스트이름 설정된다.
- InetAddess.toString() : InetAddess 객체에 저장된 네트워크 식별자를 문자열로 변환하여 반환하는 메소드
- InetAddess.getHostName() : InetAddess 객체에 저장된 네트워크 식별자에서 호스트 이름을 문자열로 변환하여 반환하는 메소드
- InetAddess.getHostAddress() : InetAddess 객체에 저장된 네트워크 식별자에서 IP 주소를 문자열로 변환하여 반환하는 메소드
실행 결과

import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAdressApp {
public static void main(String[] args) throws UnknownHostException {
InetAddress itwill = InetAddress.getByName("www.itwill.xyz");
System.out.println("[www.itwill.xyz]의 IP 주소 = " + itwill.getHostAddress());
InetAddress[] naver = InetAddress.getAllByName("www.naver.com");
for(InetAddress address : naver) {
System.out.println("[www.naver.com]의 IP 주소 = " + address.getHostAddress());
}
}
}
- InetAddress.getByName(Stirng name) : 매개변수로 전달받은 호스트이름에 대한 네트워크 식별자가 저장된 InetAddress 객체를 반환하는 메소드
- InetAddress.getAllByName(String name) : 매개변수로 전달받은 호스트이름에 대한 네트워크 식별자가 저장된 InetAddress 객체의 배열을 반환하는 메소드
실행 결과

TCP 프로그램
- TCP 프로그램은 ServerSocket 클래스와 Socket 클래스를 이용해 작성한다.
- TCP 프로그램은 서버와 클라이언트가 소켓을 사용하여 1:1로 연결되어 데이터를 송수신하는 네트워크 프로그램이다.
- 서버(Server) : 외부의 컴퓨터(클라이언트)가 접속할 수 있는 환경과 서비스를 제공하기 위한 컴퓨터를 뜻한다 → ServerSocket 클래스를 사용하여 서버 프로그램 작성
- 클라이언트(Client) : 서버에 접속하여 서비스를 제공받을 수 있는 컴퓨터 → Socket 클래스를 사용하여 클라이언트 프로그램 작성
서버-클라이언트 연결과정
- 서버는 포트를 열어놓고, 클라이언트가 접속하길 기다린다.
- 클라이언트는 Socket 클래스로 객체 만들어 IP주소와 포트 번호 통해 접속한다.
- 서버측 소켓과 클라이언트의 소켓이 1:1로 연결된다.
- 값을 송수신할 수 있는 입출력 스트림이 자동 생성된다.
ServerSocket 클래스 : 서버 프로그램을 작성하기 위해 사용하는 클래스
- ServerSocket 클래스의 ServerSocket(int port) 생성자를 이용하여 매개변수로 전달받은 포트번호를 활성화하여 ServerSocket 객체를 생성
- ServerSocket 객체를 생성하여 클라이언트가 접속할 수 있는 환경 제공 (포트가 열려야만 클라이언트가 접속할 수 있다)
- 매개변수로 전달받은 포트번호를 이미 다른 네트워크 프로그램에 사용중인경우 IOException 발생
ServerSocket 클래스를 사용하여 사용 가능한 포트번호를 검색하는 프로그램 작성
public class ServerSocketApp {
public static void main(String[] args) {
for(int i = 2000; i <= 9000; i+=1000) {
try {
ServerSocket serverSocket = new ServerSocket(i);
System.out.println("[메시지]" + i + "번 포트는 네트워크 프로그램에서 사용 가능");
serverSocket.close(); //클라이언트가 접속할 수 있는 환경 소멸
} catch (IOException e) { //포트번호를 이미 다른 네트워크 프로그램에 사용중인경우 IOException 발생
System.out.println("[메시지]" + i + "번 포트는 이미 다른 네트워크 프로그램에서 사용중입니다.");
}
}
}
}
- serverSocket.close() : serverSocket 객체를 제거하는 메소드 → 클라이언트가 접속할 수 있는 환경이 소멸된다
실행 결과

실습
접속된 클라이언트에게 서버 컴퓨터의 현재 날짜와 시간을 전달하는 서버 프로그램 작성
→ NTP(Network Time Protocol) Server : 날짜와 시간을 제공하는 서버 컴퓨터
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
public class TimeServerApp {
public static void main(String[] args) {
ServerSocket ntpServer = null;
try {
//ServerSocket 객체 생성 : 포트를 활성화하여 클라이언트가 접속할 수 있는 환경 제공
ntpServer = new ServerSocket(2000); //2000번 포트 활성화
//ServerSocket.toString() : ServerSocket 객체에 저장된 접속 관련 정보를 문자열로
//반환하는 메소드
//System.out.println("ntpServer = " + ntpServer);
System.out.println("[메세지]NTP Server Running...");
//서버 프로그램에 다수의 클라이언트 접속을 허용하도록 무한루프 사용
while(true) {
Socket socket = ntpServer.accept();
//OutputStream은 원시데이터를 전달하기 때문에, 날짜와 시간을 전달하기 위해서는
//ObjectOutputStream 클래스로 확장시켜줘야 한다.
OutputStream stream = socket.getOutputStream();
//OutputStream 객체를 전달받아 객체를 전달할 수 있는 출력스트림으로 확장
ObjectOutputStream out = new ObjectOutputStream(stream);
//출력스트림을 이용하여 시스템의 현재 날짜와 시간이 저장된 Date 객체를 생성
//하여 전달 - 클라이언트에게 날짜와 시간을 전송
out.writeObject(new Date());
//한번만 호출할 것이기 때문에 참조변수 생성 없이 만들어주는 것이 더 효율적
// - 불필요한 변수는 만들지 않는 것을 권장한다
//new ObjectOutputStream(socket.getOutputStream()).writeObject(new Date());
//로그 처리 - 기록
System.out.println("[정보]클라이언트["+socket.getInetAddress()
.getHostAddress()+"]에게 날짜와 시간을 제공 하였습니다.");
//클라이언트와의 접속 해제 >> 더 이상 받을것도, 보낼것도 없는 상태이기 때문에
socket.close();
}
} catch (IOException e) {
System.out.println("[에러]서버 네트워크에 문제가 발생 되었습니다.");
}
}
}
- ServerSocket.accept() : 클라이언트가 접속되면 클라이언트와 값을 주고 받을 수 있는 Socket 객체를 반환하는 메소드
→ 클라이언트가 접속되기 전까지 스레드 일시 중지되며, 클라이언트가 접속되면 클라이언트의 소켓과 연결될 소켓을 생성하여 반환하고 스레드를 재실행한다. - Socket.getOutputStream() : Socket 객체에 저장된 출력스트림(OutputStream 객체)을 반환하는 메소드
- Socket.getInetAddress() : 소켓과 연결된 외부 컴퓨터의 네트워크 식별자가 저장된 InetAddress 객체를 반환하는 메소드
Socket 클래스 : TCP 프로그램에서 다른 컴퓨터와의 연결을 위한 정보를 저장하기 위한 클래스
- 다른 컴퓨터의 소켓과 연결되어 값을 송수신할 수 있는 입출력 스트림 제공
→ Socket 클래스의 Socket(String Host, int port) 생성자를 이용하여 매개변수에 접속 컴퓨터(서버)의 네트워크 식별자(호스트이름 또는 IP 주소)와 활성화된 포트번호를 전달하여 Socket 객체 생성 - 서버 접속
→ UnknownHostException 및 IOException 발생 - 일반 예외이므로 반드시 예외 처리
NTP 서버에 접속하여 서버에서 보내온 날짜와 시간을 제공받아 출력하는 클라이언트 프로그램 작성
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class TimeClientApp {
public static void main(String[] args) throws ClassNotFoundException {
try {
//Socket(String Host, int port) 생성자 이용해 객체 생성 - 서버 접속
Socket socket = new Socket("192.168.13.7", 2000);
InputStream stream = socket.getInputStream();
//InputStream 객체를 전달받아 객체를 받을 수 있는 입력스트림으로 확장
ObjectInputStream in = new ObjectInputStream(stream);
//입력스트림을 이용하여 서버에서 보내온 Date 객체를 반환받아 저장
Date date = (Date)in.readObject(); //Object 타입으로 받아오기 때문에 명시적객체형변환 필요
//Date 객체에 저장된 날짜와 시간을 원하는 형식의 문자열로 변환하여 출력
System.out.println("[결과]서버에서 보내온 날짜와 시간 = "
+ new SimpleDateFormat("yyyy년 MM월 dd일 HH시 mm분 ss초").format(date));
//접속 해제
socket.close();
} catch (UnknownHostException e) {
System.out.println("[에러]서버를 찾을 수 없습니다.");
} catch (IOException e) {
System.out.println("[에러]서버에 접속할 수 없습니다.");
}
}
}
- Socket.getInputStream() : Socket 객체의 입력스트림(InputStream 객체)을 반환하는 메소드
- Socket.close() : Socket 객체를 제거하는 메소드 - 접속 해제
클라이언트에서 보내온 메세지를 제공받아 출력하는 서버 프로그램 작성
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServerApp {
public static void main(String[] args) {
ServerSocket echoServer=null;
try {
echoServer=new ServerSocket(3000);
System.out.println("[메세지]Echo Server Running...");
while(true) {
Socket socket=echoServer.accept();
//소켓의 입력스트림을 제공받아 대략의 문자데이터를 입력받을 수 있는 입력스트림 확장
BufferedReader in=new BufferedReader
(new InputStreamReader(socket.getInputStream()));
//클라이언트의 소켓과 연결된 입력스트림을 이용하여 문자열(메시지)를 반환받아 출력
System.out.println("["+socket.getInetAddress().getHostAddress()
+"]님이 보내온 메세지 = "+in.readLine());
socket.close();
}
} catch (IOException e) {
System.out.println("[에러]서버 네트워크에 문제가 발생 되었습니다.");
}
}
}
키보드로 메세지를 입력받아 접속 서버에 전달하는 클라이언트 프로그램 작성
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class EchoClientApp {
public static void main(String[] args) throws IOException {
//키보드 입력스트림을 대량의 문자데이터를 입력받을 수 있는 입력스트림으로 확장
// 원시데이터만 받아들일 수 있기 때문에 문자 데이터 읽을 수 있게 확장 >> 문자열 데이터 읽을 수 있도록 확장
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.print("전달 메세지 입력 >> ");
String message = in.readLine(); //키보드로 메세지 입력 받기
try {
Socket socket = new Socket("192.168.13.X", 3000);
/*
//소켓의 출력스트림을 제공받아 대량의 문자데이터를 전달할 수 있는 출력스트림으로 확장
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
//서버의 소켓과 연결된 출력스트림을 이용하여 문자열(메시지) 전달
out.write(message);
//출력 스트림의 버퍼에 존재하는 문자데이터를 출력스트림으로 전달
out.flush();
*/
//BufferedWriter 대신 PrintWriter 사용 가능 (더 효율적)
//소켓의 출력스트림을 제공받아 모든 자료형의 값을 문자열로 변환하여 전달할 수
//있는 기능의 출력스트림으로 확장
PrintWriter out = new PrintWriter(socket.getOutputStream());
//PrintWriter.println(Object o) : 매개변수로 전달받은 모든 자료형의 값(객체)를
//문자열로 변환하여 전달하는 메소드
out.println(message);
out.flush();
socket.close();
} catch (IOException e) {
System.out.println("[에러]서버에 접속할 수 없습니다.");
}
}
}
PrintWriter의 println() 메소드 사용하면, 어떤 형태의 값이든 문자열로 변환해 전달할 수 있다는 장점이 존재한다. 따라서, BufferedWriter 대신 PrintWriter 사용하는 것이 더 효율적이다.
UDP 프로그램
- UDP 프로그램은 DatagramSocekt 클래스와 DatagramPacket 클래스를 이용하여 작성한다.
- 값을 전달하는 컴퓨터와 값을 전달받는 컴퓨터로 구분한다. (서버, 클라이언트라는 개념이 없다.)
- 접속이라는 행위 필요 없이, 그냥 전송한다.
DatagramSocket 클래스
- 다른 컴퓨터와 연결하기 위한 정보를 저장하기 위한 클래스
- 데이터를 보내는 컴퓨터는 기본생성자를 이용해 DatagramSocket() 객체를 생성
DatagramPacket 클래스
- 연결 컴퓨터에게 보낼 패킷정보를 저장하기 위한 클래스
- DatagramPacket 클래스의 DatagramPacket(byte[] data, int length, InetAddress address, int port) 생성자를 사용하여 데이터를 보내기 위한 패킷정보가 저장된 DatagramPacket 객체 생성
실습
키보드로 메세지를 입력받아 다른 컴퓨터에게 전달하는 UDP 프로그램 작성
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class MessageSendApp {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("전달 메세지 입력 >> ");
String message = in.readLine();
//데이터를 보내는 컴퓨터는 기본생성자를 이용해 DatagramSocket() 객체를 생성
DatagramSocket socket = new DatagramSocket();
//연결할 컴퓨터의 네트워크 식별자가 저장된 InetAddress 객체를 반환받아 저장
InetAddress address = InetAddress.getByName("192.168.13.X");
byte[] data = message.getBytes();
//DatagramPacket 클래스의 DatagramPacket 생성자를 사용하여 데이터를 보내기 위한
//패킷정보가 저장된 DatagramPacket 객체 생성
DatagramPacket packet = new DatagramPacket(data, data.length, address, 4000);
socket.send(packet);
socket.close();
System.out.println("[결과]연결 컴퓨터에게 메세지를 보냈습니다.");
}
}
- String.getBytes() : String 객체에 저장된 문자열을 byte 배열로 변환하여 반환하는 메소드
- DatagramSocket.send(DatagramPacket packt) : 매개변수로 전달받은 DatagramPacket 객체의 패킷정보를 이용하여 데이터(패킷)를 전달하는 메소드
- DatagramSocket.close() : DatagramSocket 객체를 제거하는 메소드
다른 컴퓨터에서 보내온 메세지를 얻어와 출력하는 UDP 프로그램
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class MessageReceiveApp {
public static void main(String[] args) throws IOException {
//데이터를 받는 컴퓨터는 포트를 활성화하기 위해 DatagramSocket 클래스의
//DatagramSocket(int port) 생성자를 사용하여 객체 생성
DatagramSocket socket = new DatagramSocket(4000);
//패킷에 의해 전달된 값(메시지)을 저장하기 위한 byte 배열 선언
byte[] data = new byte[1024];
//데이터를 받는 컴퓨터는 DatagramPacket 클래스의 DatagramPacket(byte[] data, int length)
//생성자를 이용하여 DatagramPacket 객체 생성
DatagramPacket packet = new DatagramPacket(data, data.length);
System.out.print("메시지 수신 중...");
socket.receive(packet);
//byte 배열에 저장된 값을 제공받아 String 객체를 생성하여 저장
String message = new String(data);
System.out.println("[결과]메세지 >> " + message);
socket.close();
}
}
- DatagramSocket.receive(DatagramPacket packet) : 연결 컴퓨터에서 보내온 값(패킷)을 얻어와 DatagramPacket 객체의 byte 배열에 저장하는 메소드 → 패킷을 받기전까지 스레드 일시 중지
'학원 > 복기' 카테고리의 다른 글
[Oracle] SQL명령 / SELECT / 문자함수 (0) | 2023.05.01 |
---|---|
0428 - Database, DBMS, SQL (0) | 2023.04.29 |
0426 - 객체 직렬화, 네트워크 (0) | 2023.04.26 |
0425 - java.io 패키지, 입출력 스트림, 파일 입출력 (0) | 2023.04.25 |
0424 - javax.swing 패키지 (0) | 2023.04.24 |