티스토리 뷰

OneToOne

1.

// 알고보면 버퍼리더가 입력도 받을 수 있다.
public class SendThread extends Thread{

  private Socket m_Socket; // 변수 m_Socket 선언

  public void run() { // Thread에 있는 run 메소드를 오버라이딩

    super.run(); // 부모 run 메소드 호출
    try {
      // 얘는 키보드 입력하려고 만든 애
      BufferedReader tmpbuf = new BufferedReader(new InputStreamReader(System.in));
      // BufferReader 이용해 입력 객체 생성

      PrintWriter sendWriter = new PrintWriter(m_Socket.getOutputStream());
      // PrintWriter 객체 생성
      // 객체 생성 시, Socket의 출력 스트림 인자로 받아서 생성
      String sendString;
      while(true) {
        sendString = tmpbuf.readLine();
        // 입력 받은 값 sendString에 대입
        sendWriter.println(sendString);
        // PrintWriter의 println 메소드에 sendString 대입
        sendWriter.flush();
        // 상대방쪽으로 데이터를 밀어버림 => 상대에게 데이터가 전송
        // PrintWriter의 flush 함수 호출 시, 문자열 데이터 전송
      }
    }
    catch(IOException e) {
      e.printStackTrace();
    }
  }


  // 메인문에서 Socket 객체 받아 내 변수에 대입

  public void setSocket(Socket _socket) {
    m_Socket = _socket;
  }

}

 

2.

public class ReceiveThread extends Thread {

  private Socket m_Socket;

  public void run() {
    super.run();
    try {
      BufferedReader tmpbuf = new BufferedReader(new InputStreamReader(m_Socket.getInputStream()));
      // Socket을 이용한 BufferReader 생성
      // 이제는 소켓에서 읽겠다.
      // BufferReader를 만드는데, InputStreamReader로 받는다.
      // InputStreamReader는 소켓을 InputStream으로 받을 수 있다.
      // 이걸 하면 문자로 바로 받을 수 있다.
      // 줄 단위로 끊어서 읽을 수 있게 됨.

      String receiveString;

      while(true) {
        receiveString = tmpbuf.readLine(); // 한줄로 문자를 만듦
        // BufferReader ReadLine 저장

        if(receiveString == null) { // 데이터가 없으면
          System.out.println("상대방 연결이 끊겼습니다.");
          break;
        }
        else { // 있으면
          System.out.println("상대방: " + receiveString); // 상대방 출력
          // 여기서는 소켓에서 읽은 걸 콘솔에 쓰겠다.
        }
      }
      tmpbuf.close(); // 버퍼 닫기 연결 종료
    }
    catch(IOException e) {
      e.printStackTrace();
    }
  }

  // 메인문에서 Socket 객체 받아 내 변수에 대입

  public void setSocket(Socket _socket) {
    m_Socket = _socket;
  }
}

 

3.

// 사실상 sendThread
public class ClientThread extends Thread{

  private Socket m_Socket; // 그냥 Socket이잖아요. 이것만 봐도 이게 TCP라는 걸 알 수 있죠.

  public void run() { // 어떤 작업을 할 지 명시
    super.run();
    try {
      // new InputStreamReader(System.in) : 콘솔에서 입력을 받는다는 것 / 버퍼 이용해서 속도 좀 더 높이겠다.
      BufferedReader tmpbuf = new BufferedReader(new InputStreamReader(System.in));
      // BufferReader 이용해 입력 객체 생성
      PrintWriter sendWriter = new PrintWriter(m_Socket.getOutputStream());
      // PrintWriter 객체 생성 : 쓴다는 건데, 이 소켓에다가 쓰겠다고 선언(getOutputStream()은 쓰는 것.)
      // 객체 생성 시, Socket의 출력 스트림 인자로 받아서 생성
      String sendString;

      while(true) {
        sendString = tmpbuf.readLine(); // 여기서 입력을 받겠다.
        // 콘솔 사용자 입력을 받아서(읽는 것은 콘솔 사용자 입력에서 읽어오는 거고)
        if(sendString.equals("quit")) { // 내가 종료하게 만들기 위해서 이걸 만듦
          break; // 사용자가 quit을 치면 그만하고,
        }
        else {
          sendWriter.println(sendString); // 그게 아니면 이 Writer에게 출력을 한다.
          // 콘솔 사용자 입력에서 읽어 온 것을 그대로 sendWriter에 쓸 거다.
          sendWriter.flush();
          // sendWriter는 "여기다 쓰겠다" 해서 쓸 곳을 만들어준 것.
        }
      }
    }
    catch(IOException e) {
      e.printStackTrace();
    }
  }

  // 메인문에서 Socket 객체 받아 내 변수에 대입

  public void setSocket(Socket _socket) {
    m_Socket = _socket;
  }
}

 

4.

public class MainClient {
  // 연결하고 데이터 보내는 역할을 해주는 앤데(제어 기능)
  // ReceiveThread 에서는 사실상 설계만

  public static void main(String[] args) {

    // 그런데 여기는 ReceiveThread 만 있고 SendThread는 없어요.
    // 그냥 ClientThread를 SendThread라고 생각해도 될 거 같아요
    try {
      Socket c_socket = new Socket("192.168.10.46",9000); // Socket 생성 -> 서버 역할
      System.out.println("서버 연결");

      ReceiveThread receive_thread = new ReceiveThread(); // Receive Thread 객체 생성
      receive_thread.setSocket(c_socket); // Receive Thread Socket 전달
      ClientThread send_thread = new ClientThread(); // Client Send Thread 객체 생성
      send_thread.setSocket(c_socket); // Client Send Thread Socket 전달
      // 그래서 요 두개에다가 여기서 만든 소켓 달아주고

      // 각각 스타트를 해주면
      // send쓰레드가 데이터를 먼저 보내기 시작할거고
      send_thread.start(); // Client Thread 시작
      receive_thread.start(); // Receive Thread 시작
      // 얘는 데이터를 읽어와서 콘솔에 출력하고 요런 식으로 진행이 될 것.
    }
    catch(IOException e) {
      e.printStackTrace();
    }
  }

}
/*
헷갈림직한 것
ReceiveThread도 읽고 쓰고,
SendThread도 읽고 쓴다. 차이는 위치!!!
Send는 콘솔에서 읽어서 Socket에 썼고,
반대로 ReceiveThread는 소켓에서 읽어서
콘솔에 쓰는 것.
 */

 

5.

public class  MainServer {
  public static void main(String[] args) {

    try {
      ServerSocket a_socket = new ServerSocket(9000); // ServerSocket 객체 생성
      Socket c_socket = a_socket.accept(); // 클라이언트 쪽에 연결되면 c_socket 만들어짐.
      // 서버소켓에서 연결 요청한 애를 받아와서(클라이언트) 얘를 연결시키고
      // 누구랑 연결됐는지를  Socket c_socket 여기서 가져온 것.
      // 즉 클라이언트의 소켓이 Socket c_socket 여기 쏙 담긴다.
      // ServerSocket accept 메소드, 변수 c_socket에 대입

      ReceiveThread receive_thread = new ReceiveThread(); // Receive Thread 객체 생성
      receive_thread.setSocket(c_socket); // Receive Thread Socket 전달
      // 그럼 이 클라이언트 소켓에게 데이터를 가져와서

      SendThread send_thread = new SendThread(); // Send Thread 객체 생성
      send_thread.setSocket(c_socket); // Send Thread Socket 전달
      // 여기에서 데이터를 쓴다.



      receive_thread.start();
      send_thread.start(); // Send Thread 시작
    }
    catch(IOException e) {
      e.printStackTrace();
    }
  }

}

 

 

 

 

728x90
반응형
Comments
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
250x250