JAVA
Java Network and Thread
jmeen
2021. 8. 11. 16:10
728x90
JAVA Thread
Process: 실행중인 하나의 프로그램
Thread: 프로세스 내의 하나의 작업 흐름
Thread의 상태와 Multi Thread 프로그램의 작성 방법
Thread의 상태
상태 | 열거 상수 | 설명 |
객체 생성 | NEW | 쓰레드 객체가 생성. 아직 start() 메서드가 호출되지 않은 상태 |
실행 대기 | RUNNABLE | 실행 상태로 언제든지 갈 수 있는 상태 |
일시 정지 | WAITING | 다른 쓰레드가 통지할 때까지 기다리는 상태 |
TIMED_WAITING | 주어진 시간 동안 기다리는 상태 | |
BLOCKED | 사용하고자 하는 객체의 락이 풀릴 때까지 기다리는 상태 | |
종료 | TERMINATED | 실행을 마친 상태 |
Multi Thread 프로그램 작성 방법
- java.lang.Thread 클래스를 이용하는 방법
- java.lang.Runnable 인터페이스를 이용하는 방법
java.lang.Thread 클래스를 이용하는 방법
main 메소드를 포함하는 클래스
public class Multithread {
public static void main(String args[]) {
Thread thread = new DigitThread(); // 스레드를 생성
thread.start(); // 스레드를 시작
for (char ch = 'A'; ch <= 'Z'; ch++) {
System.out.print(ch);
}
}
}
숫자를 출력하는 스레드 클래스
public class DigitThread extends Thread {
public void run() {
for (int cnt = 0; cnt < 10; cnt++) {
System.out.print(cnt);
}
}
}
java.lang.Runnable 인터페이스 연습
Java Network and Thread - TCP Socket Programming
TCP Socket Programming : TCP 소켓의 특징
- 스트림(stream) 통신 프로토콜
- 양쪽의 소켓이 연결된 상태에서 통신이 가능하다(연결지향 프로토콜)
- 신뢰성 있는 데이터 통신
- 한번 연결되면 끊어질 때까지 송신한 데이터는 차례대로 목적지의 소켓에 전달
- 자바는 java.net 패키지에 관련 클래스를 제공
- TCP 소켓 프로그래밍을 쉽게 할 수 있도록 돕는다
- 라이브러리의 사용법과 작동 순서를 명확하게 이해하고 있어야 한다
- ServerSocket과 Socket 클래스를 사용한다
import java.net.InetAddress;
import java.net.UnknownHostException;
public class InetAddressEx {
public static void main(String[] args) {
// 내 ip 확인
try {
InetAddress local = InetAddress.getLocalHost();
System.out.println("Local IP" + local.getHostAddress());
} catch (Exception e) {
e.printStackTrace();
}
printServerIp("www.google.com");
}
private static void printServerIp(String hostName) {
try {
InetAddress[] remotes = InetAddress.getAllByName(hostName);
for (InetAddress remote : remotes) {
System.out.println(hostName + " : " + remote.getHostAddress());
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
TCP 소켓 프로그래밍 절차
ServerSocket과 Socket
ServerSocket : 클라이언트의 연결 요청을 기다리면서 연결 요청에 대한 수락을 담당
Socket : 클라이언트와 통신을 직접 담당한다
서버- 클라이언트 연동 시스템
1. 서버 구동부
package com.javaex.network.echoserver;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
// 서버 소켓
ServerSocket serversocket = null;
try {
// 바인드 : 주소와 포트 연결
serversocket = new ServerSocket();
InetSocketAddress ip = new InetSocketAddress("192.168.0.11", 10000);
serversocket.bind(ip);
System.out.println("<서버 시작>");
System.out.println("[연결을 기다립니다.]");
while (true) {
Socket socket = serversocket.accept(); // 연결 대기
Thread thread = new Thread(new ServerThread(socket));
// 쓰레드 시작
thread.start();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
serversocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
1-1. 서버 Thread
package com.javaex.network.echoserver;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.*;
public class ServerThread extends Thread {
// 소켓
private Socket socket;
// 생성자
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
// 쓰레드의 시작
// 접속 성공시 : 클라이언트 정보 확인
InetSocketAddress remote = (InetSocketAddress) socket.getRemoteSocketAddress();
System.out.println("[클라이언트가 접속되었습니다.]");
System.out.println(remote.getAddress() + ":" + remote.getPort());
// 클라이어트로부터 메세지 수진
// 스트림 열기
InputStream is = socket.getInputStream();
// 주고 받을 데이터 text -> reader
Reader isr = new InputStreamReader(is, "UTF-8");
BufferedReader br = new BufferedReader(isr);
// 클라이언트 echo back 을 하기 위한 스트림 열기
OutputStream os = socket.getOutputStream();
Writer osw = new OutputStreamWriter(os, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
// 데이터 읽기
String message;
while (true) {
message = br.readLine();
if (message == null) {
System.out.println("[접속 종료]");
break;
}
System.out.println("클라이언트로부터 메세지 : " + message);
System.out.println("Echo back : " + message);
// 클라이언트로 echo back
bw.write("[ECHO]: " + message);
bw.newLine();
bw.flush();
}
// 후처리
bw.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. 클라이언트
package com.javaex.network.echoserver;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
Socket socket = null;
try {
// 소켓 생성 : 데이터 통신용
socket = new Socket();
// 시작 메세지
System.out.println("<클라이언트 시작>");
System.out.println("[연결 요청]");
// 접속 시도
InetSocketAddress server = new InetSocketAddress("192.168.0.16", 10000);
socket.connect(server);
System.out.println("[서버에 연결되었습니다.]");
// 스트림 열기
OutputStream os = socket.getOutputStream();
Writer osw = new OutputStreamWriter(os, "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
InputStream is = socket.getInputStream();
Reader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
// 키보드에서 메세지 입력
Scanner sc = new Scanner(System.in);
// scanner에서 /q입력하면 종료
while (true) {
String message = sc.nextLine(); // 한 줄 입력
if (message.equals("/q")) {
System.out.println("종료");
break;
}
// 서버로 메세지 전송
bw.write(message);
bw.newLine();
bw.flush();
System.out.println("서버로 전송한 메세지 :" + message);
String echoMsg = br.readLine(); // 한줄 읽기
System.out.println("서버로부터 ECHO된 메시지" + echoMsg);
}
sc.close();
bw.close();
br.close();
// 종료
System.out.println("<클라이언트 종료>");
} catch (ConnectException e) {
System.err.println("[접속이 거부되었습니다.]");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}