Http 통신과 Socket 통신
→ 단방향 통신 Http 통신 (connection less)
: Http 통신은 클라이언트의 요청이 있을 때만 서버가 응답하여 해당 정보를 전송하고 곧바로 연결을 종료하는 방식이다.
클라이언트가 요청을 보내는 경우에만 서버가 응답하는 단방향 통신으로 반대로 서버가 클라이언트에게 요청을 보낼 수 없다.
→ 양방향 통신 Socket 통신 (connection pool)
: 서버와 클라이언트가 특정 포트번호를 통해 실시간으로 양방향 통신을 하는 방식이다. Http 통신과는 다르게 서버와 클라이언트가 특정 포트번호를 통해 연결되어 있어서 실시간으로 양방향 통신을 할 수 있다.
ex) 실시간 채팅, 게임 등과 같이 즉각적으로 정보를 주고 받는 경우에 사용됨.
스트림 (InputStream, OutputStream)
: 스트림은 프로그램 동작 중 외부에서 데이터를 읽거나 외부로 데이터를 출력하는 작업에 사용된다.
이때 데이터는 어떤 통로를 통해서 이동되는데 이 통로를 스트림이라고 한다.
데이터를 읽는 역할을 수행하는 InputStream과 외부로 데이터를 출력하는 OutputStream이 존재하며 이 둘은 단일 방향으로 연속적으로 흘러간다.
(단방향이라는 특징 때문에 하나의 스트림으로 입출력을 동시에 할 수 없어서 InputStream과 OutputStream이 따로 존재함.)
소켓 통신 흐름
1. 기다리는 측 Server, Server에서 Port를 열고 Client의 접속을 기다린다.
2. 접속하는 측을 Client라고 하며, Server의 IP와 Port에 접속하여 통신이 연결된다.
3. 통신이 연결되고 나면 연결 포트는 끊어지고 연결이 완료된 후에 새로운 포트 번호를 할당 받아 새로운 소켓으로 통신을 주고 받는다. (ServerSocket - 클라이언트 연결만 받는 소켓 / Socket - 실제로 통신을 하는 소켓)
4. Server와 Client 간의 통신은 BufferedReader, BufferedWriter 형태로 주고 받는다.
5. 통신이 끝나면 flush(), close()를 통해 접속을 끊는다.
단방향 통신 예제
Server.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | package ch02; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; // 소켓 통신을 구현 // 1. 서버측과 클라이언트 측은 통신을 통해 데이터를 주고 받는다. // 서버측 만들 때 서버 소켓을 준비해야 한다. // 소켓은 양 끝단에 포트 번호를 달아야 한다. // 0 ~ 65335번까지 포트 번호를 사용할 수 있다. // 그 중에 0 ~ 1023번 포트 번호까지는 잘 알려진 포트 번호라 사용 안하는 것이 좋다. public class Server { // 클라이언트 연결만 받는 소켓 ServerSocket serverSocket; // 실제로 통신을 하는 소켓 Socket socket; BufferedReader bufferedReader; public Server() { System.out.println(">> 서버 소켓 시작 <<"); try { // 서버 소켓을 포트 번호와 함께 생성 serverSocket = new ServerSocket(11001); // 클라이언트 접속 대기중 socket = serverSocket.accept(); System.out.println(">> 클라이언트 연결 완료 <<"); bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); while (true) { String getMsg = bufferedReader.readLine(); System.out.println("서버측에서 확인 : " + getMsg); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new Server(); } } // end of class | cs |
Client.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | package ch02; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; import java.net.UnknownHostException; // 소켓 통신을 하려면 소켓이 필요하다. ( 서버측 연결을 담당하는 포트 번호를 알아야 함.) public class Client { final String IP = "localhost"; Socket socket; BufferedWriter bufferedWriter; BufferedReader bufferedReader; public Client() { try { System.out.println("클라이언트 소켓 프로그램 시작"); socket = new Socket(IP, 11001); System.out.println("소켓으로 연결 완료"); // 소켓에다가 버퍼 스트림 연결 bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 키보드에서 값을 받아 서버측으로 보내기 bufferedReader = new BufferedReader(new InputStreamReader(System.in)); while(true) { System.out.println("글자를 입력해주세요."); String keyMsg = bufferedReader.readLine(); bufferedWriter.write(keyMsg + "\n"); bufferedWriter.flush(); } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { new Client(); } } | cs |
- 클라이언트 측에서 받은 메세지를 서버 측에서 파일을 생성해 출력하는 예제
Server.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | package ch03; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; public class Server { // 연결만 주고 받을 서버 소켓 (연결만 하고 끊어짐.) ServerSocket serverSocket; // 실제 통신을 할 소켓 필요 Socket socket; BufferedReader bufferedReader; BufferedWriter bufferedWriter; public Server() { try { // 서버 소켓을 생성함과 동시에 연결할 포트 번호 serverSocket = new ServerSocket(10002); socket = serverSocket.accept(); // 클라이언트와 연결 완료 // 입력을 위한 socket의 기반스트림을 불러오기 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // mj.txt파일로 출력할 예정 bufferedWriter = new BufferedWriter(new FileWriter("c:/tmp/mj.txt")); // 문자열을 null일 때까지 읽음 String str; while((str = bufferedReader.readLine())!= null) { bufferedWriter.write(str); } } catch (IOException e) { e.printStackTrace(); }finally { try { // 물내려주고 닫음. bufferedWriter.flush(); bufferedWriter.close(); bufferedReader.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { new Server(); } } | cs |
Client.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | package ch03; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; import java.net.UnknownHostException; // 소켓 통신을 하려면 소켓이 필요하다. (서버측 연결 담당 포트 번호 알아야 함.) public class Client { // 자신의 ip final String IP = "localhost"; Socket socket; BufferedReader bufferedReader; BufferedWriter bufferedWriter; public Client() { try { // 소켓 생성과 동시에 ip, 연결 담당 포트 번호 socket = new Socket(IP, 10002); // 키보드로 받은 내용을 읽을 예정 bufferedReader = new BufferedReader(new InputStreamReader(System.in)); // 출력을 위한 소켓의 기반 스트림 불러오기. bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 이 부분에서 while(true)로 해서 무한 반복이 일어나 server측 코드가 flush()가 되지 않았었음. boolean flag = true; while (flag == true) { String msg = bufferedReader.readLine(); System.out.println("Client 측 메세지 " + msg); bufferedWriter.write(msg + "\n"); bufferedWriter.flush(); flag = false; } } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { bufferedWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { new Client(); } } | cs |
'프로그래밍 > 개인 복습 공부' 카테고리의 다른 글
Java_I/O 입출력 스트림 파일 생성하기 (0) | 2023.04.14 |
---|