IT 개발/Java

[Java] 자바 - 소켓통신이란? 소켓(Socket) 개념과 사용방법

KADOSHOLY 2022. 8. 8. 08:17
반응형

 

자바 - 소켓통신이란? 소켓(Socket) 개념과 사용방법

 

 

네트워크를 통해 데이터를 주고받을 수 있도록 지원하는 소켓(Socket) 통신에 대해서 알아보도록 하겠습니다. 

 

 

   목차

  1. 소켓(socket)과 소켓통신이란?
  2. 서버와 클라이언트
  3. 서버 소켓 구현하기
  4. 클라이언트 소켓 구현하기
  5. BufferedReader/BufferedWrite와 PrintWriter, PrintStream
  6. 소켓통신 사용예제1 (1:1 채팅 프로그램)
  7. 소켓통신 사용예제2 (멀티 채팅 프로그램)

 

 

1. 소켓(Socket)과 소켓통신이란?

 

소켓(Socket)은 TCP/IP 기반 네트워크 통신에서 데이터 송수신의 마지막 접점을 말합니다. 소켓통신 이러한 소켓을 통해 서버-클라이언트간 데이터를 주고받는 양방향 연결 지향성 통신을 말합니다. 소켓통신은 보통 지속적으로 연결을 유지하면서 실시간으로 데이터를 주고받아야 하는 경우에는 사용됩니다. 

 

소켓은 클라이언트 소켓과 서버 소켓으로 구분되며, 소켓간 통신을 위해서는 네트워크상에서 클라이언트와 서버에 해당되는 컴퓨터를 식별하기 위한 IP주소와 해당 컴퓨터내에서 현재 통신에 사용되는 응용프로그램을 식별하기 위한 포트번호가 사용됩니다. 

 

 

 

2. 서버와 클라이언트

 

소켓통신에서는 서버와 클라이언트가 존재하며, 서버(Server)는 데이터를 제공하는 쪽을 말하며, 클라이언트(Client)는 데이터를 요청하여 제공받는 쪽을 말합니다. 

 

 

 

3. 서버 소켓 구현하기

 

1) 서버소켓 생성

    ServerSocket serverSocket = new ServerSocket(8000);  // 포트번호

 

2) 클라이언트 접속 대기

    Socket socket = serverSocket.accept( );

 

3) 데이터 송수신을 위한 input/output 스트림 생성 

    InputStream in = socket.getInputStream( );

    OutputStream out = socket.getOutputStream( );

 

4) input 스트림을 통한 데이터 수신 (클라이언트 → 서버)

    byte[ ] inputData = new byte[100];

    int length = in.read(inputData);

    String inputMessage = new String(inputData, 0, length);

 

5) output 스트림을 통한 데이터 송신 (서버 → 클라이언트) 

    String outputMessage = "보낼메시지";

    out.write(outputMessage.getBytes( ));

    out.flush( );

 

6) 통신 종료

    socket.close( );

    serverSocket.close( );

 

 

 

4. 클라이언트 소켓 구현하기

 

1) 클라이언트 소켓 생성을 통한 서버접속

    Socket socket = new Socket("127.0.0.1", 8000);  // IP주소, 포트번호

 

2) 데이터 송수신을 위한 input/output 스트림 생성 

    InputStream in = socket.getInputStream( );

    OutputStream out = socket.getOutputStream( );

 

3) output 스트림을 통한 데이터 송신 (클라이언트 → 서버)

    String outputMessage = "보낼메시지";

    out.write(outputMessage.getBytes( ));

    out.flush( );

 

4) input 스트림을 통한 데이터 수신 (서버 → 클라이언트)

    byte[ ] inputData = new byte[100];

    int length = in.read(inputData);

    String inputMessage = new String(inputData, 0, length);

 

5) 통신 종료

    socket.close( );

 

반응형

 

 

5. BufferedReader/BufferedWriter와 PrintWriter, PrintStream

 

데이터 전송의 기본단위는 바이트(byte)로 문자의 경우 데이터 전송시 문자를 바이트로, 수신시 바이트를 문자로 변환이 필요합니다. 이를 위해서 앞에서는 String클래스의 생성자와 getBytes메소드를 이용했습니다. 

 

자바에는 이 변환을 편리하게 해주는 클래스로 InputStreamReader와 OutputStreamWriter가 있으며 charset을 지정하여 사용할 수 있습니다. 또한 데이터 입출력의 효율을 위해 바로 전달하지 않고 중간에 버퍼를 이용하기 위해서 BufferedReader와 BufferedWriter 클래스를 함께 사용할 수 있습니다. 

 

  ex) BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream( )));

  ex) BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream( )));

 

 

데이터 출력의 경우에는 출력 포맷을 편리하게 해주는 기능이 있는 PrintWriter 또는 PrintStream 클래스를 사용할 수 있습니다. 

 

  ex) PrintWriter out = new PrintWriter(socket.getOutputStream( ));

  ex) PrintStream out = new PrintStream(socket.getOutputStream( ));

 

 

 

6. 소켓통신 사용예제1 (1:1 채팅 프로그램)

 

1) 서버

public class MyServer {
	public static void main(String[] args) {
		BufferedReader in = null;
		PrintWriter out = null;
		
		ServerSocket serverSocket = null;
		Socket socket = null;
		Scanner scanner = new Scanner(System.in);
		
		try {
			serverSocket = new ServerSocket(8000);
			
			System.out.println("[Server실행] Client연결대기중...");
			socket = serverSocket.accept();			// 연결대기

			System.out.println("Client 연결됨.");
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			out = new PrintWriter(socket.getOutputStream());
						
			while(true) {
				String inputMessage = in.readLine();	// 수신데이터 한줄씩 읽기	
				if ("quit".equalsIgnoreCase(inputMessage)) break;
				
				System.out.println("From Client: " + inputMessage);
				System.out.print("전송하기>>> ");
				
				String outputMessage = scanner.nextLine();
				out.println(outputMessage);
				out.flush();
				if ("quit".equalsIgnoreCase(outputMessage)) break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				scanner.close();		// Scanner 닫기
				socket.close();			// Socket 닫기
				serverSocket.close();		// ServerSocket 닫기
				System.out.println("연결종료");
			} catch (IOException e) {
				System.out.println("소켓통신에러");
			}
		}
	}
}

 

2) 클라이언트

public class MyClient {
	public static void main(String[] args) {
		BufferedReader in = null;
		PrintWriter out = null;
		
		Socket socket = null;
		Scanner scanner = new Scanner(System.in);
		
		try {
			socket = new Socket("127.0.0.1", 8000);
			
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			out = new PrintWriter(socket.getOutputStream());
			
			while(true) {
				System.out.print("전송하기>>> ");
				String outputMessage = scanner.nextLine();
				out.println(outputMessage);
				out.flush();
				if ("quit".equalsIgnoreCase(outputMessage)) break;
								
				String inputMessage = in.readLine();
				System.out.println("From Server: " + inputMessage);
				if ("quit".equalsIgnoreCase(inputMessage)) break;
			}
		} catch (IOException e) {
			System.out.println(e.getMessage());
		} finally {
			try {
				scanner.close();
				if (socket != null) socket.close();
				System.out.println("서버연결종료");
			} catch (IOException e) {
				System.out.println("소켓통신에러");
			}
		}
	}
}

 

3) 실행결과

소켓통신 프로그램 실행결과
서버 클라이언트간 데이터 주고받기 실행결과

 

 

 

7. 소켓통신 사용예제2 (멀티 채팅 프로그램)

 

멀티 스레드를 이용한 멀티채팅 프로그램 예제는 아래 글을 참고하세요.

 

2022.08.10 - [IT 개발/Java] - [Java] 자바 - 멀티채팅 프로그램 구현하기

 

[Java] 자바 - 멀티채팅 프로그램 구현하기

자바 - 멀티채팅 프로그램 구현하기 앞서 자바 소켓통신 내용에서는 TCP/IP기반 통신에서 서버와 클라이언트가 데이터를 서로 주고 받는 법에 대해서 알아보았습니다. 여기에서는 멀티스레드를

kadosholy.tistory.com

 

 

반응형