이번에는 1:1 채팅 프로그램으로


채팅을 한번 하고 끝나지 않기 위해서는 반복문을 돌려야만 한다.


또한 통신 기능 외의 작업이 같이 돌아가야 하기 때문에 Thread를 이용한다.






메시지를 받을 서버 Receiver 클래스



package chap12.exam04.chat;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class Receiver extends Thread {
	private Socket socket = null;

	public Receiver(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try {
			// 4. InputStream으로 보내온 메시지를 받는다.
			InputStream is = socket.getInputStream(); // 핵심
			BufferedInputStream bis = new BufferedInputStream(is);
			InputStreamReader reader = new InputStreamReader(bis, "UTF-8");
			char[] arr = new char[100];
			while(is != null) {  // 스트림으로 반복문 제어
				// 5. 출력
				reader.read(arr);
				// ㅁㅁㅁ는 \0이고 배열의 공백을 의미한다.
				String msg = new String(arr).replace('\0', ' ');
				System.out.println("[상대] " + msg);

				// 긴 문장 후 짧은 문장이 들어올 경우 이전 값과 섞여 들어온다.
				// 초기화
				arr = new char[100];
			}
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	}

}



메시지를 받을 클라이언트 Sender 클래스



package chap12.exam04.chat;

import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

public class Sender extends Thread {
	private Socket socket = null;
	
	public Sender(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try {
			// 입력값을 받는 Scanner
			Scanner scan = new Scanner(System.in);
			// OutputStream으로 보내온 메시지를 전송한다.
			OutputStream os = socket.getOutputStream();
			BufferedOutputStream bos = new BufferedOutputStream(os);
			OutputStreamWriter writer = new OutputStreamWriter(bos, "UTF-8");

			while(os != null) {
				String msg = scan.nextLine();
				writer.write(msg);
				writer.flush();
				
			}
			
			scan.close();
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	}

}





Receiver와 Sender을 Thread로 만들어 실행해준다.




Server


package chap12.exam04.chat;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class ChatServer {

	public static void main(String[] args) {

		try {
			// 1. 소켓 생성(bind 생략 가능)
			ServerSocket server = new ServerSocket(5001);
			// 2. 접속 수락
			Socket socket = server.accept();
			System.out.println("접속 수락");
			// 3. 받기 전용 스레드 실행
			Receiver receiver = new Receiver(socket);
			receiver.start();
			// 4. 전송 전용 스레드 실행
			Sender sender = new Sender(socket);
			sender.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}





Client


package chap12.exam04.chat;

import java.net.Socket;

public class ChatClient {

	public static void main(String[] args) {
		try {
			// 1. 소켓 생성
			Socket socket = new Socket("여기에 IP를 입력해야 정상적으로 동작해요", 5001);
// 2. 연결 요청 // 3. 받기 전용 스레드 실행 Receiver receiver = new Receiver(socket); receiver.start(); // 4. 전송 전용 스레드 실행 Sender sender = new Sender(socket); sender.start(); } catch (Exception e) { System.out.println(e.toString()); } } }


10번째 줄에 접속할 대상의 IP를 입력해주어야 하고 1개의 컴퓨터로 테스트 할 경우


대상 Server가 자기 자신이므로 자신의 IP를 입력하면 된다.


그리고 서버는 이클립스에서 실행하고


클라이언트를 따로 실행해야 하는데


https://qdgbjsdnb.tistory.com/79 를 참조하여 cmd에서 클라이언트를 작동해보자.

+ Recent posts