전체 방문자
오늘
어제
21종
종이의 코딩 공부방
21종
  • 분류 전체보기 (174)
    • JAVA (64)
    • Springboot (46)
      • 블로그만들기 (45)
    • Database (60)
      • Oracle (60)
    • 프로젝트 3 (CELOVER) (0)
    • 개발서버 구축 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

최근 글

최근 댓글

hELLO · Designed By 정상우.
21종

종이의 코딩 공부방

JAVA

[자바/JAVA] 프로그래밍 - Network_서버, 클라이언트 통신

2023. 6. 22. 15:51

* 현재 구동중인 서버가 있으면 클라이언트 그 서버로 요청 보낼 수 있음! => 응답결과 돌려줌

- 요청과 응답에 의해서 프로그램은 돌아감! ("통신"한다 표현)
- 웹에서의 통신방식 : HTTP 프로토콜 통신

* 자바만을 가지고 서버와 클라이언트 간의 간단한 통신 해보기!!
  이때 데이터를 입출력하고자 한다면 서버와 클라이언트 간의 스트림(연결통로)이 필요함!

* 소켓 : 프로세스간의 통신을 담당하는 것! (스트림을 연결하기 위한 문)


* 소켓 프로그래밍 (TCP 방식 / UDP 방식)

- TCP 방식 : 데이터 전송속도가 느림! 데이터가 정확하고 안정적으로 전달 가능함! (신뢰성이 요구되는 프로그램 : http, 이메일) (클라이언트가 요청하고 서버가 응답하는 느낌)


- UDP 방식 : 데이터 전송속도가 빠름! 신뢰성 없는 데이터 전달 될 수 있음! (데이터를 빠른 속도로 전송하고자 하는 프로그램 : 실시간 동영상 서비스) (클라이언트가 일방적으로 요청하는 느낌)


TCP(Transmission Control Protocol)


- 서버, 클라이언트 간의 1 : 1 소켓 통신
- 데이터를 교환하기에 앞서서 서버, 클라이언트가 연결되어있어야함! (서버가 먼저 실행되어 클라이언트의 요청 기다릴꺼임)
- 신뢰성 있는 데이터 전달 가능

* 소켓(Socket)
- 프로세스간의 통신을 담당
- Input / OutputStream을 가지고 있음! (이 스트림을 통해 입출력이 이루어짐)

* Server Socket
- 포트와 연결되어(Bind) 외부의 연결 요청을 기다리다 연결요청 들어오면 수락해줄 용도

  수락 => 통신 할 수 있는 Client Socket 생성



Server

package com.kh.chap02_tcp.run;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class ServerProgram {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		// 입력 보조스트림
		BufferedReader br = null;
		
		// 한줄씩 읽어오는 출력보조스트림
		PrintWriter pw = null;
		
		// 1) 포트 번호 지정 (서버측에서 몇 번 포트로 통로를 열꺼냐)
		int port = 3000;
		
		ServerSocket server = null;
		
		try {
			// 2) Server Socket 객체 생성시 포트 결합(bind) => (ServerSocket은 클라이언트의 연결 요청을 받아줄 용도의 소켓)
			server = new ServerSocket(port);
			
			// 3) 클라이언트로부터 접속 요청이 올 때 까지 대기상태...
			System.out.println("클라이언트의 요청을 기다리고 있어요...");
			
			// 4) 연결 요청이 오면 요청 수락 후 해당 클라리언트와 통신 할 수 있는 서버측 소켓 객체 생성
			Socket socket = server.accept();	// socket == 클라이언트와 통신할 수 있는 소켓 객체
			System.out.println(socket.getInetAddress().getHostAddress() + "가 연결을 요청함...");
		
			// 5) 클라이언트와 입출력 스트림 생성(바이트 스트림으로 밖에 안됨! => 1byte 짜리!) => 성능이 별로 안좋음
			
			// 6) 보조스트림을 통해서 성능 개선
			// 입력용 스트림 => 1바이트 짜리 바이트 스트림을 문자스트림으로 변경해줌!! => 성능 더 좋은 보조스트림 껴서
			br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
			// 출력용 스트림 (클라이언트에게 값을 한 줄 단위로 출력할 수 있는 출력용 스트림)
			pw = new PrintWriter(socket.getOutputStream()); 
			// PrintWritter : 데이터 출력 print(), println() 메소드 가지고 있는 보조스트림
			
			// 7) 스트림을 통해 읽고 쓰기
			// 클라이언트로부터 전달된 메세지가 있을 경우 서버측 읽어들일거임! (입력)
			while(true) {
				String message = br.readLine();
				System.out.println("클라이언트로 부터 전달받은 메시지 : " + message);
				
				// 반대로 클라이언트에게 데이터 전달 (출력!)
				System.out.print(socket.getInetAddress().getHostAddress() + "클라이언트에게 보낼 내용 : ");
				String sendMessage = sc.nextLine();
				
				pw.println(sendMessage); // 클라이언트에게 출력
				pw.flush();	// 현재 스트림에 있는 데이터를 강제로 내보내는 메소드 => close() 할 때 자동 호출됨
				
				
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 8) 통신 종료
			try {
				pw.close();
				br.close();
				server.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

Client

package com.kh.chap02_tcp.run;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class ClientProgram {
	
	public static void main(String[] args) {
		
		// 클라이언트용 프로그램
		
		Scanner sc = new Scanner(System.in);
		
		BufferedReader br = null;
		PrintWriter pw = null;
		
		Socket socket = null;
		
		// 요청하고자 하는 서버 ip : 자신의 IP 주소, 컴퓨터가 두대가 없으니까 내가 서버와 클라이언트 두개의 역할을 해보자
		// 포트번호 : 3000

		int port = 3000;
		String serverIP;		
		
		try {
			serverIP = "자신의 IP주소";
			// 1) 서버에 연결 요청 보내는 구문 (요청하고자 하는 서버의 IP주소와 지정된 포트번호를 제시하면서 소켓 객체 생성)
			socket = new Socket(serverIP, port);
			// 서버꺼져있거나 못찾으면 (통신실패) null 이 담김
			
			if(socket != null) {// 서버와 잘 연결됐을 경우
				System.out.println("서버와 연결 성공!!");
				
				// 2) 서버와 입출력 기반스트림 생성
				// 3) 보조스트림 통해서 성능 개선
				
				// 입력용 스트림
				br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
				// 출력용 스트림
				pw = new PrintWriter(socket.getOutputStream());
				
				while(true) {
					// 4) 스트림을 통해 읽고 쓰기
					System.out.print("서버에게 보낼 내용 : ");
					String sendMessage = sc.nextLine();
					
					pw.println(sendMessage);
					pw.flush();
					
					String message = br.readLine();
					System.out.println("서버에게 전달받은 메시지 : " + message);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			// 5) 통신 종료
			try {
				pw.close();
				br.close();
				
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

실행

 

먼저 ServerProgram을 실행 한 후 이어서 ClientProgram을 실행한다.

New Console View 를 클릭하여 콘솔을 두개 띄워준다.

 

둘다 ClientProgram 콘솔이 뜨기 때문에 하나의 콘솔을 ServerProgram콘솔로 바꿔준다.
이렇게 뜨면 성공

먼저 클라이언트 콘솔에서 보내고 싶은 말을 보내면 Sever에 뜨게된다.

그 후 서버에서도 보내면 클라이언트 콘솔에 출력된다,

    'JAVA' 카테고리의 다른 글
    • [자바/JAVA] 프로그래밍 - Network_InetAddress
    • [자바/JAVA] 프로그래밍 - 종합 예제 (도서관 프로그램)
    • [자바/JAVA] 프로그래밍 - 종합 예제(MVC)
    • [자바/JAVA] 프로그래밍 - Map (HashMap, Properties)
    21종
    21종
    코딩 공부한 것 정리하려고 만든 블로그

    티스토리툴바