본문 바로가기

Java SE/Socket 08

Socket 08

클라이언트가 전송한 글을 서버측에서 받아서 전송한 이용자의 IP 주소를 글의 왼쪽에 붙여서 접속중인 모든 이용자에게 전달하는 내용을 추가함

서버측 코드

import java.net.*;
import java.io.*;
import java.util.*;

/* 글을 전송한 이용자의 IP 주소를 글의 왼쪽에 붙이고, 이용자가 전송한 문자열을 그대로
* 다른 접속자에게 전달될 수 있게 하였다.
*/
class  ChatServer {
 static Vector<Socket>v = new Vector<Socket>();

 public static void main(String[] args) throws Exception {
 
  ServerSocket ss = new ServerSocket(1234);
  System.out.println("서버 실행중....");

  while(true) {
   Socket soc = ss.accept();
   new UserThread(soc).start();
   v.add(soc);
   System.out.println("클라이언트 입장");
  }
 }

 /* 내부클래스, 클라이언트와 데이터교환 쓰레드*/
 static class UserThread extends Thread  {
  BufferedReader br;
  PrintWriter pw;
  Socket soc;

  UserThread(Socket soc) {
   this.soc = soc;
   try{
    br = new BufferedReader(new InputStreamReader(soc.getInputStream()));
    pw = new PrintWriter(new OutputStreamWriter(soc.getOutputStream()));
   }catch(Exception e){
    e.printStackTrace();
    System.err.println("스트림 생성 실패");
   }
  }

  public void run() {
   String line = null;
   Socket s = null;
   PrintWriter out = null;
   try{
    while((line=br.readLine())!= null) {
     /* 접속중인 모든 이용자에게 메시지를 전달한다*/
     for(int i=0;i<v.size();i++) {
      s = v.get(i);
      out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
      String ip = s.getInetAddress().getHostAddress();
      out.println(ip+": "+line);
      out.flush();
     }
     Thread.sleep(20);
    }
   }catch(Exception soce){
    soce.printStackTrace();
    System.out.println("클라이언트 나감");
    System.out.println("접속자수:"+v.size());
   }
  }// end of run()
 }// end of UserThread class
} // End of ChatServer class



클라이언트 측 코드

import java.net.*;
import java.io.*;
/* 서버측으로 데이터를 전송하는 부분과 수신하는 부분을 쓰레드로 분리하여 병행처리하도록 수정함*/
class  ChatClient {

 static PrintWriter pw;
 static BufferedInputStream bin;
 static BufferedReader keyboard;

 public static void main(String[] args) throws Exception {

  Socket soc = new Socket("172.16.16.253", 1234);

  pw = new PrintWriter(new OutputStreamWriter(soc.getOutputStream()));
  bin = new BufferedInputStream(soc.getInputStream());
  keyboard = new BufferedReader(new InputStreamReader(System.in));
 
  new SendThread().start(); // 키보드로부터 입력을 받아서 서버에 전송한다
  new ReceiveThread().start(); // 서버에서 데이터를 수신하여 모니터에 출력한다.
 }

 /* 송신기능 메소드*/
 private static void send() {
  String dan = null;
  while(true) {
   System.out.print("글 입력: ");
   try{
    dan = keyboard.readLine();
    pw.println(dan);
    pw.flush();
    Thread.sleep(20);
   }catch(Exception e){e.printStackTrace();}
  }
 }
 
 /* 수신기능 메소드*/
 private static void receive() {
  int count = 0;
  byte[] buf = null;
  int read = 0;

  while(true) {
   try{
    Thread.sleep(20);
    count = bin.available();
    if(count==0) continue;
    buf = new byte[count];
    read=bin.read(buf, 0, buf.length);
    System.out.println();
    System.out.println(new String(buf, 0, read));
   }catch(Exception e){e.printStackTrace();}
  }
 }

 /* 내부 클래스로 선언한 송신 쓰레드*/
 static class SendThread extends Thread  {
  public void run() {
   ChatClient.send();
  }
 }

 /* 내부 클래스로 선언한 수신 쓰레드*/
 static class ReceiveThread extends Thread  {
  public void run() {
   ChatClient.receive();
  }
 }
}