// UnicastServer
package net;
import java.io.*;
import java.net.*;
// TCP
public class UnicastServer {
private UnicastServerThread ust; // 유니캐스팅 서버 스레드
private ServerSocket serverS; // 실제 데이터가 어떻게 전송되는지 상관않고 읽기/쓰기 인터페이스를 제공함.
// TCP/IP 계층의 TCP를 지원하기 위해 Socket, SeverSocket 클래스를 제공
// 서버는 SocketServer 객체를 생성하여 TCP 연결을 청취해 클라이언트와 서버가 연결됨.
public UnicastServer(int port) {
// 서버 소켓 생성 (포트)
try {
serverS = new ServerSocket(port);
// 서버 소켓 생성자는 tcp 포트번호를 매개변수로 받음.
// 포트를 이용하여 서버소켓 객체를 생성함.
// 클라이언트의 연결을 받기 위해선 객체를 생성
// 자신을 바로 사용하는것이 아니라 클라이언트의 tcp 요청에 대한 socket 객체를 생성하는 역할을 함.
}catch(IOException ioe) {
ioe.printStackTrace();
System.exit(0);
}
// 서버 소켓으로 청취
while(true) { // 무한루프로 가동
try {
// 소켓 생성 후.accept()함수로 대기
// 서버 소켓의 주요작업은 들어오는 연결 요청들을 수신하고 각 요청으로부터 객체를 생성 accept()
// 클라이언트에 들어오는 요청이 없다면 올때까지 accept메서드는 블럭화되거나 타임아웃이 되면 종료됨.
// 클라의 tcp요청이 있을 때까지 블로킹 되는 메서드임
// 클라의 tcp 요청이 오면 클라와 통신할 수 있는 tcp소켓을 반환함.
// 클라이언트의 tcp 요청이 오면 accept 메서드를 통해 socket 객체를 생성한 후 다른 클라이언트의 tcp 요청을 기다리게 되므로 무한루프 처리해야함.
System.out.println("클라이언트의 요청을 기다리는 중");
Socket tcpSocket = serverS.accept(); // 일반적인 무한루프 처리
System.out.println("클라이언트의 IP 주소 :"+tcpSocket.getInetAddress().getHostAddress());
System.out.println("--- 서버 ---");
// 유니캐스팅 스레드
ust = new UnicastServerThread(tcpSocket); // 서버의 소켓 포트를 쓰레드에 인자값으로 전달
Thread thread = new Thread(ust);
thread.start();
}catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
public static void main(String[] args) {
new UnicastServer(3000);
}
}
// UnicastClient
package net;
import java.io.*;
import java.net.*;
public class UnicastClient {
private String ip;
private int port;
private String str;
BufferedReader file;
BufferedWriter bufferW;
BufferedReader bufferR;
Socket tcpSocket;
public UnicastClient(String ip, int port) throws IOException{
this.ip = ip;
this.port = port;
try {
tcpSocket = getSocket();
// 클라이언트는 Socket 객체를 생성해 TCP 서버와 연결을 시도한다.
System.out.println("서버 연결");
System.out.println("---클라이언트---");
OutputStream os_socket = tcpSocket.getOutputStream();
InputStream is_socket = tcpSocket.getInputStream();
bufferW = new BufferedWriter(new OutputStreamWriter(os_socket));
bufferR = new BufferedReader(new InputStreamReader(is_socket));
while(true){
// 첫번째 클라이언트에서 전달할 메세지 입력
System.out.print("입력 : ");
file = new BufferedReader(new InputStreamReader(System.in));
str = file.readLine(); // 파일에 생성된 입력값을 str변수에 저장
if(str.equals("exit")) { // 종료 후 null값 전달을 방지하기위한 조건문
str = "exit";
str += System.getProperty("line.separator");
bufferW.write(str);
bufferW.flush(); // 출력 버퍼를 비움 반드시해야하는것.
System.out.println("종료되었습니다.");
break;
}
str += System.getProperty("line.separator");
bufferW.write(str);
bufferW.flush(); // 출력 버퍼를 비움 반드시해야하는것.
// 서버에서 보내온 메세지 출력
str = bufferR.readLine();
System.out.println("Server Result : " + str);
}
}
catch(IOException ioe) {
ioe.printStackTrace();
}finally {
System.out.println("Client End");
if(file != null) file.close();
if(bufferW != null) bufferW.close();
if(bufferR != null) bufferR.close();
if(tcpSocket != null) tcpSocket.close();
}
}
public Socket getSocket() {
Socket tcpSocket = null;
try {
tcpSocket = new Socket(ip, port);
}catch(IOException ioe) {
ioe.printStackTrace();
System.exit(0);
}
return tcpSocket;
}
public static void main(String[] args) throws IOException {
new UnicastClient("localhost", 3000);
}
}
// UnicastServerThread
package net;
import java.io.*;
import java.net.*;
public class UnicastServerThread implements Runnable {
private Socket tcpSocket;
private BufferedReader bufferR;
private BufferedWriter bufferW;
BufferedReader file;
// private String str;
public UnicastServerThread(Socket tcpSocket) {
this.tcpSocket = tcpSocket;
}
@Override
public void run() {
try {
// 소켓을 이용한 입출력 스트림
// 클라이언트와 서버간 통신 가능한 인아웃풋
// 버퍼의 스트림 생성이 실패되면 while문이 돌지 않는다.
bufferR = new BufferedReader(new InputStreamReader(tcpSocket.getInputStream()));
bufferW = new BufferedWriter(new OutputStreamWriter(tcpSocket.getOutputStream()));
} catch (IOException e1) {
e1.printStackTrace();
}
try {
while (true) {
// 클라에서 보내온 메세지 출력
String messageC = bufferR.readLine();
System.out.println("수신메시지 : " + messageC);
// 서버에서 보낸 메시지 다시 클라로 보내기
System.out.print("발신메세지 : ");
file = new BufferedReader(new InputStreamReader(System.in));
messageC = file.readLine();
if(messageC.equals("exit")) { // null값 출력을 방지하기 위한 조건문
messageC = "exit";
messageC += System.getProperty("line.separator");
bufferW.write(messageC); // 줄바꿈
bufferW.flush(); // 출력 버퍼 지우기
System.out.println("종료되었습니다.");
break; // while문 탈출
}
messageC += System.getProperty("line.separator");
bufferW.write(messageC);
bufferW.flush(); // 출력 버퍼 지우기
}
} catch (SocketException se) {
System.out.println("종료되었습니다.");
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
try {
System.out.println("Thread End");
if(file != null) file.close();
if(bufferW != null) bufferW.close();
if(bufferR != null) bufferR.close();
if(tcpSocket != null) tcpSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
----- 출력
반응형
'자바과정 > Java' 카테고리의 다른 글
객체 지향 프로그래밍 4대 특징 (코드 실습) (0) | 2021.09.09 |
---|---|
객체 지향 프로그래밍이란 (0) | 2021.09.09 |
Java 기초 - 11일차 (0) | 2021.02.19 |
Java 실습(ArrayList & HashMap) - 10일차 (0) | 2021.02.18 |
Java 실습(스택 : 제네릭) - 10일차 (0) | 2021.02.18 |
댓글