본문 바로가기
자바과정/Java

Java 팀 실습(유니캐스트 Client&Server 에서 서로 메세지 주고받기) - 10일차

by Parkej 2021. 2. 22.

// 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();
			}
		}
	}
}

 

 

----- 출력

서버의 출력
클라이언트의 출력

 

서버의 출력

반응형

댓글