Old Branch

Java Socket Server(TCP/IP) 소켓 프로그래밍

woolbro 2019. 6. 27. 12:50
반응형

안녕하세요, 이번 포스팅은 Server Side 까지 고려한 TCP/IP Java Socket 프로그래밍 입니다.

 

Client는 아래 포스팅을 참고 해 주세요

[Java/Java Study] - Java Socket Client (TCP/IP) 소켓 프로그래밍

 

Java Socket Client (TCP/IP) 소켓 프로그래밍

이번 포스팅에서는 Java Socket 프로그래밍에 대해서 포스팅 하려고 합니다 :) TCP/IP 프로토콜을 사용하여 서버와 통신하는 클라이언트 프로그램을 작성하는 방법입니다. 클라이언트 소켓 API Socket 클래스는 소..

woolbro.tistory.com

 

 

Server Socket API

ServerSocket의 클래스는 서버 프로그램을 구현하는데 사용됩니다. 일반적인 서버 프로그램의 과정은 Step1 ~ Step 6으로 나눌 수 있습니다.

 

Step 1. 서버 소켓 생성, 포트 바인딩

Step 2. 클라이언트로부터의 연결을 기다리고(Connect Listen) 요청이 오면 수락

Step 3. 클라이언트 소켓에서 가져온 InputStream(클라이언트 쪽에서는 OuputStream 이 됩니다)을 읽음

Step 4. 응답이 있다면 OutputStream을 통해 클라이언트에 데이터를 보냄

Step 5. 클라이언트와의 연결을 닫음

Step 6. 서버 종료

 

사용 목적이나 용도에 따라서 3~4단계는 반복 될 수 있습니다!

 

설명드릴 통신의 순서는 

Create a Server Socket -> Listen for a connection -> Read data from the client -> Send Data to the Client -> Close the client Connection -> Terminate the Server

입니다!!

 

Step 1. Create a Server Socket

다음 생성자 중 하나를 사용하여 ServerSocket 클래스의 새 객체를 만듭니다.

create ServerSocket

- ServerSocket(int port) : 지정된 포트 번호에 바인딩 된 서버 소켓을 만듬 (연결 대기열 최대 수 50)

- ServerSocket(int port, int backlog): 지정된 포트 번호에 바인드 된 서버 소켓을 만들고 대기중인 최대 연결 수를 backlog 매개변수로 지정

- ServerSocket(int port, int backlog, InetAddress bindAddr) : 서버 소켓을 만들고 지정된 포트 번호와 로컬 IP 주소에 바인딩

 

 

간단한 사용 예 입니다. 서버 소켓을 포트번호 8000에 바인딩하는 예 입니다.

ServerSocket serverSocket = new ServerSocket(8000);

 

이러한 생성자는 소켓을 열 때 I/O Exception이 일어 날 수 있기 때문에 고려 해 주어야 합니다.

 

Step 2. Listen for a connection

 

연결 수신의 예 입니다.

Socket socket = serverSocket.accept();

 

Step 3. Read data from the Client

 

Socket 객체가 반환 되면 (연결이 되면) InputStream을 사용하여 클라이언트에서 보낸 데이터를 읽을 수 있습니다.

InputStream input = socket.getInputStream();

 

InputStream은 데이터를 byte 배열로 읽기 때문에, 상위 레벨의 데이터를 읽으려면 InputStreamReader 읽어줍니다.

InputStreamReader reader = new InputStreamReader(input);
int character = reader.read();  // reads a single character

 

또한 BufferedReader에 InputStream을 래핑하여 데이터를 String으로 읽어옵니다.

BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line = reader.readLine();    // reads a line of text

 

Step 4. Send Data to the client

 

Socket과 연결 된 클라이언트에게 OutputStream을 사용하여 데이터를 보냅니다.

OutputStream output = socket.getOutputStream();

 

PintWriter를  사용하여 텍스트 형식으로 데이터를 보낼 수 있습니다.

PrintWriter writer = new PrintWriter(output, true);
writer.println(“This is a message sent to the server”);

 

Step 5. Close the client Connection

 

Socket 통신이 완료 되면, close() 메서드를 사용하여 클라이언트와의 연결을 종료합니다.

socket.close();

close() 메서드는 소켓의 InputStreamOutputStream을 닫아 주는 역할을 합니다.

 

 

Step 6. Terminate the Server

 

서버는 클라이언트에서 들어오는 요청을 기다리며 항상 실행되어 있어야 합니다.

서버를 중지 해야 하는 경우에는 ServerSocket 인슽턴스의 close() 메서드를 호출하여 서버를 종료 해 줍니다.

Client Connection을 종료하는 메서드와 명칭이 같지만, Client와의 연결을 끊는 것이 아니라 "서버"를 중지하는 역할을 합니다.

serverSocket.close();

 

 

 

 

Java Server Socket Example

- Client 코드

package com.woolbro.dev.socket.Client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TimeClient {

    public static void main(String[] args) {
        if (args.length < 2) {
            System.out.println("#######Need More Arguments #########");
            return;
        }

        String hostname = args[0];
        int port = Integer.parseInt(args[1]);
        for (int i = 0; i < 10; i++) {
            try (Socket socket = new Socket(hostname, port)) {
                OutputStream out = socket.getOutputStream();
                String realStr = "This is woolbro dev Test";
                out.write(realStr.getBytes());
                InputStream input = socket.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(input));

                String time = reader.readLine();

                System.out.println(time);

            } catch (UnknownHostException ex) {

                System.out.println("Server not found: " + ex.getMessage());

            } catch (IOException ex) {

                System.out.println("I/O error: " + ex.getMessage());
            }
        }

    }

}

 

- Server 코드

 

package com.woolbro.dev.socket.Server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class TimeServer {

    public static void main(String[] args) {
        if (args.length < 1) {
            System.out.println("######## Argument is Null ########");
            return ;
        }
        
        int port = Integer.parseInt(args[0]);
 
        try (ServerSocket serverSocket = new ServerSocket(port)) {
 
            System.out.println("Server is listening on port " + port);
 
            while (true) {
                Socket socket = serverSocket.accept();
 
                System.out.println("[ "+socket.getInetAddress()+" ] client connected");
                OutputStream output = socket.getOutputStream();
                PrintWriter writer = new PrintWriter(output, true);
                writer.println(new Date().toString());

                InputStream input = socket.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(input));
                System.out.println("###### msg : "+reader.readLine());
            }
 
        } catch (IOException ex) {
            System.out.println("Server exception: " + ex.getMessage());
            ex.printStackTrace();
        }

    }

}