TIL(2022.03.05)

조지성·2022년 3월 5일
0

TIL

목록 보기
40/78
post-thumbnail

소켓통신(양방향 통신)

서버소켓

package ch07.socket3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerFile {
	// 클라이언트 연결을받는 소켓
	ServerSocket serverSocket;
	// 실제 통신을 하는 소켓
	Socket socket;
	BufferedReader br;

	BufferedWriter bw; // 새로운 스레드가 필요하다.
	BufferedReader keyboard; // 새로운 스레드가 필요하다.

	public ServerFile() {
		System.out.println("1. 서버 소켓 시작-----------");
		try {
			serverSocket = new ServerSocket(10000);
			System.out.println("2. 서버소켓 생성완료 : 클라이언트 접속대가------");
			socket = serverSocket.accept(); // 클라이언트 접속 대기중...
			System.out.println("3.클라이언트 연결 완료----buffer 연결완료(read)");

			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			keyboard = new BufferedReader(new InputStreamReader(System.in));
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

			// write 스레드 실행(글쓰기)
			WriteThread wt = new WriteThread();
			Thread t1 = new Thread(wt);
			t1.start();

			// main 스레드 역활 (글 읽기)
			while (true) {// 지속되게
				String msg = br.readLine();
				System.out.println("클라이언트로 부터 받으 메시지 : " + msg);
			}
		} catch (Exception e) {
			System.out.println("서버소켓 에러 발생함" + e.getMessage());
		}
	}

	// 내부 클래스
	class WriteThread implements Runnable {

		@Override
		public void run() {
			while (true) {
				try {
					String keyboardMsg = keyboard.readLine();
					bw.write(keyboardMsg + "\n");
					bw.flush();
				} catch (Exception e) {
					System.out.println("서버소켓에서 키보드 입력받는 중 오류발생 : " + e.getMessage());
				}
			}
		}

	}

	public static void main(String[] args) {
		new ServerFile();
	}
}

클라이언트 소켓

package ch07.socket3;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class ClientFile {
	Socket socket;
	BufferedWriter bw;
	BufferedReader keyboard;

	// 새로운 스레드 필요
	BufferedReader br;

	public ClientFile() {
		// 소켓 연결
		try {
			System.out.println("1. 클라이언트 소켓 시작-----------");
			socket = new Socket("localhost", 10000); // 서버소켓이 accept()메서드 호출

			System.out.println("2. 버퍼(write)연결완료 -----------");
			bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

			// 키보드 연결
			System.out.println("3.키보드 스트림 + 버퍼(read)연결완료 -----------");
			keyboard = new BufferedReader(new InputStreamReader(System.in));

			br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

			// 새로운 스레드 역활(글 읽기)
			ReadThread rt = new ReadThread();
			Thread t1 = new Thread(rt);
			t1.start();

			// 메인 스레드의 역활(글쓰기)
			while (true) { // 지속되게
				System.out.println("4.키보드 입력 대기중 -----------");
				String keyboardMsg = keyboard.readLine();

				// 메세지의 끝을 알려줘야한다 \n
				bw.write(keyboardMsg + "\n");
				bw.flush(); // 강제로 버퍼 비워줌
			}
		} catch (Exception e) {
			System.out.println("서버소켓 에러 발생함" + e.getMessage());
		}
	}

	class ReadThread implements Runnable {

		@Override
		public void run() {
			while (true) {
				try {
					String msg = br.readLine();
					System.out.println("서버로 부터 메세지 : " + msg);
				} catch (Exception e) {
					System.out.println("클라이언트 소켓에서 서버소켓 메세지 입력받는 중 오류발생 : " + e.getMessage());
				}
			}

		}

	}

	public static void main(String[] args) {
		new ClientFile();
	}
}

웹소켓

스프링 입문을 위한 자바 객체지향의 원리와 이해

자바는 절차적/구조적 프로그래밍의 유산

  • 절차적/구조적 프로그래밍의 흔적은 메서드에서 찾을 수 있다.
    => 순서 , 제어는 모두 메서드안에서만 이루어지기 때문이다
  • 함수 vs 메서드
    : 함수 - 클래스나 객체와 관련이 없는 함수
    : 메서드 - 클래스 안에 존재하는 함수
    : 자바는 클래스 안에서 이루어지기 때문에 함수랑 메서드는 같은 말이다.

실행순서

package ex02;

public class Start {
	public static void main(String[] args) {
		System.out.println("Hello");
	}
}
  1. JRE는 먼저 프로그램 안에 main() 메서드가 있는지 확인
  2. main()메서드의 존재가 확인되면 JRE는 프로그램 실행을 위한 사전 준비에 착수
  3. JVM부팅
  4. JVM은 목적파일을 실행
  5. JVM은 java.lang 패키지를 스태틱 영역에 가져다 놓음
  6. JVM은 개발자가 작성한 모든 클래스와 임포트 패키지 역시 스태틱 영역에 가져다 놓는다.
    7.스택 프레임에 main() 메서드가 할당
  7. args를 저장할 변수 공간을 main 스택 프레임 맨 밑에 확보
  8. print출력
  9. 닫는 중괄호를 만나면서 main 스택 영역 종료 메모리에서 사라짐
  10. JVM 종료
  11. JRE 종료

변수와 메모리

JVM은 변수를 위한 공간을 메모리 차곡차곡 공간을 마련한다.

package ex02;

public class Start2 {
	public static void main(String[] args) {
		int i; // main() 스택 안에 변수 i 4바이트 공간을 만들어놓음
		i = 10; // 해당 공간에 10을 넣어줌
		
		double d = 20.0; // 공간을 만듬과 동시에 할당
	}
}

블록 스택 프레임

if문은 메서드의 스택 프레임이 아니라 if문, 그것도 참인 블록의 스택 프레임
main() 메서드의 스택 프레임 안에 if 문의 블록 스택 프레임이 중첩되어 생선된다.

package ex02;

public class Start2 {
	public static void main(String[] args) {	
		int i = 10;
		int k =20;
		
		//main 스택 프레임안에 if문의 블록 스택 프레임이 중첩됨
		if(i==10) {
			int m = k+5;
			k = m;
		}else {
			int p =k+10;
			k = p;
		}
		// 블록 스택 프레임이 끝나는 순간 m가 p값은 사라짐
		
		//k = m+ p;
	}
}

스택 프레임에 갇혔어요

변수는 어디에 있는가?
: 변수는 메모리에 있다 == 변수는 스태틱 영역, 스택 영역, 힙 영역 세 군대 모두에 있을 수 있다.

  1. 지역 변수

    • 스택 영역에 있는 변수를 지역 변수라고한다.
    • 스택 프레임이 사라지면 함께 사라진다.
  2. 클래스 멤버 변수

    • 스태틱 영역에서 일생을 보낸다.
    • JVM이 종료 될때까지 고정된 상태로 그 자리를 지킨다.
  3. 객체 멤버 변수

    • 힙에서 일생을 보낸다.
    • 가비지 컬렉터에 의해서 수거 된다.

외부 스택 프레임에서 내부 스택 프레임의 변수에 접근하는 것은 불가능하나 그 역은 가능하다.

profile
초보 개발자의 성장기💻

0개의 댓글