산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> java

자바 네트워킹 마스터하기: java.net으로 견고한 네트워크 애플리케이션 구축

네트워크 프로그래밍(network programming)은 여러 장치(컴퓨터들)에서 실행되며, 이 장치들이 네트워크를 사용하여 모두 서로 연결된 프로그램들을 작성하는 것을 의미합니다.

J2SE API의 java.net 패키지에는 저수준 통신 세부사항을 제공하는 클래스들과 인터페이스들의 모음이 들어 있어, 당면한 문제 해결에 집중하는 프로그램들을 작성할 수 있게 합니다.

java.net 패키지는 두 가지 일반적인 네트워크 프로토콜을 지원합니다.

이 장에서는 다음 두 주제에 대한 좋은 이해를 제공합니다.

소켓 프로그래밍(Socket Programming)

소켓은 TCP를 사용하여 두 컴퓨터 간 통신 메커니즘을 제공합니다. 클라이언트 프로그램은 통신 끝단에 소켓을 생성하고 그 소켓을 서버에 연결하려 시도합니다.

연결이 성립되면 서버는 통신 끝단에 소켓 객체를 생성합니다. 이제 클라이언트와 서버는 소켓에 쓰고 읽음으로써 통신할 수 있습니다.

java.net.Socket 클래스는 소켓을 나타내며, java.net.ServerSocket 클래스는 서버 프로그램이 클라이언트를 기다리고 연결을 설정하는 메커니즘을 제공합니다.

소켓을 사용하여 두 컴퓨터 간 TCP 연결을 설정할 때 다음 단계들이 발생합니다.

연결이 설정되면 I/O 스트림을 사용하여 통신할 수 있습니다. 각 소켓은 OutputStream과 InputStream을 모두 가집니다. 클라이언트의 OutputStream은 서버의 InputStream에 연결되고, 클라이언트의 InputStream은 서버의 OutputStream에 연결됩니다.

TCP는 양방향 통신 프로토콜이므로 데이터가 두 스트림을 통해 동시에 전송될 수 있습니다. 소켓 구현을 위한 완전한 메서드 세트를 제공하는 유용한 클래스들:

ServerSocket 클래스 메서드

java.net.ServerSocket 클래스는 서버 애플리케이션이 포트를 얻고 클라이언트 요청을 대기하는 데 사용됩니다.

ServerSocket 클래스에는 네 가지 생성자가 있습니다.

번호 메서드 및 설명
1public ServerSocket(int port) throws IOException - 지정된 포트에 바인딩된 서버 소켓 생성 시도. 다른 애플리케이션이 이미 포트를 바인딩한 경우 예외 발생
2public ServerSocket(int port, int backlog) throws IOException - 이전 생성자와 유사, backlog 매개변수는 대기 큐에 저장할 수신 클라이언트 수 지정
3public ServerSocket(int port, int backlog, InetAddress address) throws IOException - 이전 생성자와 유사, InetAddress 매개변수는 바인딩할 로컬 IP 주소 지정. 여러 IP 주소를 가진 서버에서 어떤 IP로 클라이언트 요청을 받을지 지정 가능
4public ServerSocket() throws IOException - 언바운드 서버 소켓 생성. 이 생성자 사용 시 서버 소켓을 바인딩할 준비가 되면 bind() 메서드 사용

ServerSocket 생성자가 예외를 던지지 않으면 애플리케이션이 지정된 포트에 성공적으로 바인딩되어 클라이언트 요청을 받을 준비가 된 것입니다.

ServerSocket 클래스의 일반적인 메서드들:

번호 메서드 및 설명
1public int getLocalPort() - 서버 소켓이 대기 중인 포트 반환. 생성자에서 포트 번호로 0을 전달하여 서버가 포트를 찾게 한 경우 유용
2public Socket accept() throws IOException - 수신 클라이언트 대기. 지정된 포트에서 클라이언트가 서버에 연결되거나 소켓 타임아웃이 발생할 때까지 블록(setSoTimeout()으로 타임아웃 값 설정된 경우). 그렇지 않으면 무한정 블록
3public void setSoTimeout(int timeout) - 서버 소켓이 accept() 동안 클라이언트를 기다릴 타임아웃 값 설정
4public void bind(SocketAddress host, int backlog) - SocketAddress 객체에 지정된 서버와 포트에 소켓 바인딩. 인수 없는 생성자로 ServerSocket 인스턴스화한 경우 이 메서드 사용

ServerSocket이 accept()를 호출하면 클라이언트가 연결될 때까지 메서드가 반환되지 않습니다. 클라이언트가 연결되면 ServerSocket은 미지정 포트에 새 Socket을 생성하고 이 새 Socket에 대한 참조를 반환합니다. 이제 클라이언트와 서버 간 TCP 연결이 존재하며 통신을 시작할 수 있습니다.

Socket 클래스 메서드

java.net.Socket 클래스는 클라이언트와 서버가 서로 통신하는 데 사용하는 소켓을 나타냅니다. 클라이언트는 Socket 객체를 인스턴스화하여 얻고, 서버는 accept() 메서드의 반환 값으로 Socket 객체를 얻습니다.

Socket 클래스에는 클라이언트가 서버에 연결하는 데 사용하는 다섯 가지 생성자가 있습니다.

번호 메서드 및 설명
1public Socket(String host, int port) throws UnknownHostException, IOException - 지정된 서버의 지정된 포트에 연결 시도. 이 생성자가 예외를 던지지 않으면 연결 성공, 클라이언트가 서버에 연결됨
2public Socket(InetAddress host, int port) throws IOException - 이전 생성자와 동일하나 호스트가 InetAddress 객체로 표시됨
3public Socket(String host, int port, InetAddress localAddress, int localPort) throws IOException - 지정된 호스트와 포트에 연결하며 로컬 호스트에 지정된 주소와 포트에 소켓 생성
4public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) throws IOException - 이전 생성자와 동일하나 호스트가 String 대신 InetAddress 객체로 표시됨
5public Socket() - 비연결 소켓 생성. connect() 메서드로 이 소켓을 서버에 연결

Socket 생성자가 반환되면 단순히 Socket 객체를 인스턴스화하는 것이 아니라 지정된 서버와 포트에 실제로 연결을 시도합니다.

Socket 클래스의 관심 메서드들입니다. 클라이언트와 서버 모두 Socket 객체를 가지므로 이 메서드들은 양쪽에서 호출 가능합니다.

번호 메서드 및 설명
1public void connect(SocketAddress host, int timeout) throws IOException - 소켓을 지정된 호스트에 연결. 인수 없는 생성자로 Socket 인스턴스화한 경우에만 필요
2public InetAddress getInetAddress() - 이 소켓이 연결된 다른 컴퓨터의 주소 반환
3public int getPort() - 소켓이 원격 머신에 바인딩된 포트 반환
4public int getLocalPort() - 소켓이 로컬 머신에 바인딩된 포트 반환
5public SocketAddress getRemoteSocketAddress() - 원격 소켓 주소 반환
6public InputStream getInputStream() throws IOException - 소켓의 입력 스트림 반환. 입력 스트림은 원격 소켓의 출력 스트림에 연결됨
7public OutputStream getOutputStream() throws IOException - 소켓의 출력 스트림 반환. 출력 스트림은 원격 소켓의 입력 스트림에 연결됨
8public void close() throws IOException - 소켓 닫음. 이 Socket 객체가 더 이상 어떤 서버에도 연결할 수 없게 됨

InetAddress 클래스 메서드

이 클래스는 인터넷 프로토콜(IP) 주소를 나타냅니다. 소켓 프로그래밍 시 필요할 유용한 메서드들:

번호 메서드 및 설명
1static InetAddress getByAddress(byte[] addr) - 원시 IP 주소로 InetAddress 객체 반환
2static InetAddress getByAddress(String host, byte[] addr) - 제공된 호스트 이름과 IP 주소로 InetAddress 생성
3static InetAddress getByName(String host) - 호스트 이름으로 호스트의 IP 주소 결정
4String getHostAddress() - 텍스트 표현으로 IP 주소 문자열 반환
5String getHostName() - 이 IP 주소의 호스트 이름 얻기
6static InetAddress getLocalHost() - 로컬 호스트 반환
7String toString() - 이 IP 주소를 String으로 변환

소켓 클라이언트 예제

다음 GreetingClient는 소켓을 사용하여 서버에 연결하고 인사말을 보낸 뒤 응답을 기다리는 클라이언트 프로그램입니다.

예제


// File Name: GreetingClient.java
import java.net.*;
import java.io.*;

public class GreetingClient {
    public static void main(String[] args) {
        String serverName = args[0];
        int port = Integer.parseInt(args[1]);

        try {
            System.out.println("Connecting to " + serverName + " on port " + port);
            Socket client = new Socket(serverName, port);
            System.out.println("Just connected to " + client.getRemoteSocketAddress());

            OutputStream outToServer = client.getOutputStream();
            DataOutputStream out = new DataOutputStream(outToServer);
            out.writeUTF("Hello from " + client.getLocalSocketAddress());

            InputStream inFromServer = client.getInputStream();
            DataInputStream in = new DataInputStream(inFromServer);
            System.out.println("Server says " + in.readUTF());

            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

소켓 서버 예제

다음 GreetingServer 프로그램은 명령줄 인수로 지정된 포트 번호에서 클라이언트들을 대기하는 Socket 클래스를 사용하는 서버 애플리케이션 예제입니다.

예제


// File Name: GreetingServer.java
import java.net.*;
import java.io.*;

public class GreetingServer extends Thread {
    private ServerSocket serverSocket;

    public GreetingServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        serverSocket.setSoTimeout(10000);
    }

    public void run() {
        while (true) {
            try {
                System.out.println("Waiting for client on port " + serverSocket.getLocalPort() + "...");
                Socket server = serverSocket.accept();
                System.out.println("Just connected to " + server.getRemoteSocketAddress());

                DataInputStream in = new DataInputStream(server.getInputStream());
                System.out.println(in.readUTF());

                DataOutputStream out = new DataOutputStream(server.getOutputStream());
                out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress() + "\nGoodbye!");

                server.close();
            } catch (SocketTimeoutException s) {
                System.out.println("Socket timed out!");
                break;
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }
        }
    }

    public static void main(String[] args) {
        int port = Integer.parseInt(args[0]);
        try {
            Thread t = new GreetingServer(port);
            t.start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

클라이언트와 서버를 컴파일한 뒤 서버를 다음과 같이 시작하세요.


$ java GreetingServer 6066
Waiting for client on port 6066...

클라이언트 프로그램을 다음과 같이 확인하세요.

출력


$ java GreetingClient localhost 6066
Connecting to localhost on port 6066
Just connected to localhost/127.0.0.1:6066
Server says Thank you for connecting to /127.0.0.1:6066
Goodbye!

java

  1. Java 연산자 마스터하기: 종류, 문법, 실전 예제
  2. Java 주석: 종류, 사용법, 모범 사례
  3. Java 향상된 for 루프(for-each) 완벽 가이드: 문법, 예제, 비교
  4. Java String 마스터하기: 생성, 메서드, 모범 사례
  5. Java 인터페이스 마스터: 개념, 구현, 모범 사례
  6. Java 익명 내부 클래스 마스터: 정의, 문법, 실전 예제
  7. Java Try-with-Resources 마스터: 자동 리소스 관리 완전 해설
  8. Java 애너테이션 완전 해설: 종류, 배치 위치, 실전 예제
  9. Java Assertion(어설션) 실전 가이드: 버그 조기 발견과 코드 신뢰성 확보
  10. Java Vector 완벽 가이드: 사용법, 특징, ArrayList와의 비교