yoni

[32][Network] Thread 문자열 전송 기반의 1:1 채팅 서버/클라이언트 본문

java of educational by contents

[32][Network] Thread 문자열 전송 기반의 1:1 채팅 서버/클라이언트

yoni-1117 2018. 12. 15. 13:21
 
1. 서버
 
▷ network.ChatServer.java
-------------------------------------------------------------------------------------
package network;
 
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;
import java.util.Scanner;
 
/*
 
java network.ChatServer
 
*/
public class ChatServer {
 
  private Socket socket = null;
  private ServerSocket server = null;
 
  public void serverStart() {
    System.out.println("접속자를 기다리는 중입니다.");
    try {
      server = new ServerSocket(2010);
      socket = server.accept(); // 진행 중지, 대기
 
      // socket으로부터 데이터를 읽어오는 스레드
      Thread read = new Thread(new ChatServerRead(socket));
      read.start();
 
      // 키보드에서 입력받아 socket으로 데이터를 보내는 스레드
      Thread send = new Thread(new ChatServerSend(socket));
      send.start();
 
    } catch (IOException ioe) {
      System.err.println("연결이 되어 있지 않습니다.");
    } finally {
      try {
        server.close();
      } catch (IOException ignored) {
      }
    }
 
  }
 
  public static void main(String[] args) {
    ChatServer cs = new ChatServer();
    cs.serverStart();
  }
}
 
/**
 * 데이터를 읽어옵니다.
 * 
 * @author stu
 * 
 */
class ChatServerRead implements Runnable {
  private Socket socket;
  private String line; // 서버로부터 읽어온 문자열 저장
 
  public ChatServerRead(Socket socket) {
    this.socket = socket;
  }
 
  public void run() {
    BufferedReader reader = null;
 
    try {
 
      reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      
      while (true) {
        // 네트웍으로부터 전송 받음, Enter로 끝나는 문자열 입력 대기
        line = reader.readLine(); 
 
        if (line == null) { // 네트워크 종료
          break; // 종료
        }
        
        System.out.println("\n" + line); // 문자열이 있는 경우 화면 출력
        System.out.print("홍길동▶ ");
      }
 
    } catch (IOException ignored) {
    } finally {
      try {
        reader.close();
      } catch (IOException ignored) {
      }   
      try {
        socket.close();
      } catch (IOException ignored) {
      }
    }
  }
 
}
 
/**
 * 데이터를 보냅니다.
 * 
 * @author stu
 * 
 */
class ChatServerSend  implements Runnable {
  private Socket socket;
  private BufferedWriter writer;
  private Scanner in;
  private String str = "";
 
  public ChatServerSend(Socket socket) {
    this.socket = socket;
  }
 
  public void run() {
    try {
      // 네트워크 출력
      writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
      // reader = new BufferedReader(new InputStreamReader(System.in));
      in = new Scanner(System.in);
 
      while (true) {
        System.out.print("홍길동▶ ");
        str = in.nextLine(); // 키보드로부터 입력 대기
        if (str.equals("exit")) {
          break; 
        }
        writer.write("홍길동▷ " + str);
        writer.newLine(); // 줄바뀜 기호가 있어야 BufferedReader의 readLine()이 인식함
        writer.flush(); // client로 전송
      }
    } catch (Exception ignored) {
 
    } finally {
      try {
        writer.close();
      } catch (IOException ignored) {
      }
      try {
        socket.close();
      } catch (IOException ignored) {
      }
      
      in.close();
    }
  }
 
}
 
  
 
-------------------------------------------------------------------------------------
 
 
2. 클라이언트
 
▷ network.ChatClientThread.java
-------------------------------------------------------------------------------------
package network;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
 
/*
 
java network.ChatClient 172.16.7.100
 
*/
public class ChatClient {
  private Socket socket = null;
 
  public void clientStart(String ip, int port) {
    System.out.println("클라이언트 프로그램 작동.....");
    try {
      socket = new Socket(ip, port); // 서버로 접속 시도
 
      // socket으로부터 데이터를 읽어오는 스레드
      Thread read = new Thread(new ChatClientRead(socket));
      read.start();
 
      // 키보드에서 입력받아 socket으로 데이터를 보내는 스레드
      Thread send = new Thread(new ChatClientSend(socket));
      send.start();
 
 
    } catch (IOException ioe) {
      System.err.println("연결이 되어 있지 않습니다.");
    } finally {
      try {
        if (socket == null) {
          socket.close();
        }
      } catch (IOException ignored) {
      }
    }
 
  }
 
  public static void main(String[] args) {
    ChatClient cc = new ChatClient();
    cc.clientStart(args[0], 2010); // ip, port
  }
}
 
/**
 * 데이터를 네트웍으로부터 읽어옵니다.
 * 
 * @author stu
 * 
 */
class ChatClientRead implements Runnable {
  private Socket socket;
  private String line; // 서버로부터 읽어온 문자열 저장
 
  public ChatClientRead(Socket socket) { // 생성자
    this.socket = socket;
  }
 
  public void run() {
    BufferedReader reader = null;
    try {
      reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      while (true) {
        line = reader.readLine(); // 네트웍으로부터 전송 받음
 
        if (line == null) {
          break;
        }
 
        // 화면 출력
        System.out.println("\n" + line);
        System.out.print("홍길순▶ ");
      }
    } catch (IOException ignored) {
      System.err.println("연결이 되어 있지 않습니다.");
    } finally {
      try {
        reader.close(); // reader cannot be resolved
      } catch (IOException ignored) {
      }
      try {
        socket.close();
      } catch (IOException ignored) {
      }
    }
  }
 
}
 
/**
 * 데이터를 보냅니다.
 * 
 * @author stu
 * 
 */
class ChatClientSend implements Runnable {
  private Socket socket;
  private BufferedWriter writer;
  private Scanner in;
  private String str = "";
 
  public ChatClientSend(Socket socket) {  // 생성자
    this.socket = socket;   
  }
 
  public void run() {
    try {
      writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 네트워크 전송
      in = new Scanner(System.in);
 
      while (true) {
        System.out.print("홍길순▶ ");
        str = in.nextLine(); // 키보드로부터 입력 대기
        if (str.equals("exit")) {
          break; 
        }
        writer.write("홍길순▷ " + str);
        writer.newLine(); // 줄바뀜 기호가 있어야 BufferedReader의 readLine()이 인식함
        writer.flush();   // 전송
      }
    } catch (Exception ignored) {
 
    } finally {
      try {
        writer.close();
      } catch (IOException ignored) {
      }
      try {
        socket.close();
      } catch (IOException ignored) {
      }
      
      in.close();
    }
  }
 
 
 
-------------------------------------------------------------------------------------
 
 
 
* package의 실행
  패키지 밖에서 실행 할 것.
 
  /ws_java/oop/bin> java network.ChatServer
 
  /ws_java/oop/bin> java network.ChatClient 127.0.0.1
 


Comments