[Java] Socket Programming

Jane·2021년 2월 1일
0
post-thumbnail

소켓 프로그래밍

  • 소켓(socket)을 이용한 통신 프로그래밍

socket

  • 프로세스 간 통신에 사용되는 양쪽 끝단(endpoint)
  • InputStream과 OutputStream을 통해 프로세스 간의 통신이 이루어진다.
  • 여러 개의 소켓이 하나의 포트를 공유 할 수 있다.

ServerSocket

  • 포트와 bind되어 포트를 통해 클라이언트의 연결 요청을 기다리다가 연결 요청이 올 때마다 새로운 소켓을 생성
    → 클라이언트의 소켓과 통신할 수 있도록 연결한다.
  • 한 포트에 하나의 ServerSocket만 연결 할 수 있다(포트 독점).
    ※ 단, 프로토콜이 다르면 같은 포트를 공유할 수 있다.

정리: 서버소켓은 소켓 간 연결만 처리하고, 실제 데이터 통신은 소켓들 간에 이루어진다.


TCP 소켓 프로그래밍

  • 클라이언트와 서버 간의 일대일 통신

서버 - 클라이언트 프로그램 간 통신 과정
1. 서버 프로그램은 서버소켓(ServerSocket)을 사용해서 서버 컴퓨터의 특정 포트에서 클라이언트의 연결 요청을 처리할 준비를 한다.
2. 클라이언트 프로그램은 접속할 서버의 IP주소와 포트 정보를 가지고 소켓을 생성해서 서버에 연결을 요청한다.
3. 서버소켓은 클라이언트의 연결 요청을 받으면 서버에 새로운 소켓을 생성해서 클라이언트의 소켓과 연결한다.
4. 클라이언트의 소켓과 새로 생성된 서버의 소켓은 서버소켓과 관계 없이 일대일 통신을 한다.


실습

TCP/IP 서버

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

class TcpIpServer {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;

        try {
            // 서버소켓을 생성, 7777 포트와 binding
            serverSocket = new ServerSocket(7777);
            System.out.println(getTime() + " 서버 준비 완료");
        } catch (IOException e) {
            e.printStackTrace();
        }

        while (true) {
            try {
                System.out.println(getTime() + " 연결 요청 대기");
                // 서버소켓은 클라이언트의 연결요청이 올 때까지 실행을 멈추고 기다린다.
                // 클라이언트의 연결요청이 오면 클라이언트 소켓과 통신할 새로운 소켓을 생성한다. 
                Socket socket = serverSocket.accept();
                System.out.println(getTime() + socket.getInetAddress());
                
                // 소켓의 출력스트림을 얻는다.
                OutputStream out = socket.getOutputStream();
                DataOutputStream dos = new DataOutputStream(out);

                // 원격 소켓(remote socket)에 데이터를 보낸다.
                dos.writeUTF("[Notice] Test Message from Server. First Socket Programming");
                System.out.println(getTime() + " 데이터를 전송했습니다.");

                // 스트림과 소켓을 닫아준다.
                dos.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    static String getTime() {
        SimpleDateFormat f = new SimpleDateFormat("[hh시 mm분 ss초]");
        return f.format(new Date());
    }
}
  • 실행 결과
  • accept() 메서드

    public Socket accept()

    • Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made.
    • A new Socket s is created and, if there is a security manager, the security manager's checkAccept method is called with s.getInetAddress().getHostAddress() and s.getPort() as its arguments to ensure the operation is allowed. This could result in a SecurityException.
    • Returns: the new Socket

TCP/IP 서버와 통신하기 위한 클라이언트 프로그램

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.Socket;

public class TcpIpClient {
    public static void main(String[] args) {
        try {
            String serverIp = "127.0.0.1";
            System.out.println("서버에 연결중입니다. 서버IP :" + serverIp);
            // 소캣을 생성하여 연결을 요청한다.
            Socket socket = new Socket(serverIp, 7777);

            // 소켓의 입력스트림을 얻는다.
            InputStream in = socket.getInputStream();
            DataInputStream dis = new DataInputStream(in);

            // 소켓으로부터 받은 데이터를 출력한다.
            System.out.println("서버로부터 받은 메시지: " + dis.readUTF());
            System.out.println("연결을 종료합니다.");
            
            dis.close();
            socket.close();
            System.out.println("연결 종료");
        } catch (ConnectException ce) {
            ce.printStackTrace();
        } catch (IOException ie) {
            ie.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 실행 결과

Source

0개의 댓글