J-한솔넷

멀티쓰레드를 이용한 채팅 프로그램 본문

프로그래밍/JAVA

멀티쓰레드를 이용한 채팅 프로그램

jhansol 2012. 10. 20. 15:33

학생듥 수업을 위한 만든 프로그램으로 기존 책의 내용이 정상적으로 동작하지 않는 관꼐로 책의 니용을 수정하여 배포한 것입니다.


이 프로그램은 콘솔 기반에서 동작하는 프로그램이나 클라이언트 프로그램을 약간만 수정하면 GUI 방식의 프로그램으로 전환할 수 있습니다.


총 4개의 클래스로 되어 있는데 각 클래스별 기능은 아래와 같습니다.

ChatServer : 서버 소캣을 생성하고 클라이언트의 접속을 받아 쓰레드를 만들어 클라이언터늬 처리를 하도록 합니다.

ChatServerThread : 클라이언트의 서비스를 직접적으로 처리하는 프로그램으로 클라이언트의 메시지를 연결된 다른 클라이언트에 전송하는 역활을 담당합니다.

ChatClient : 소캣을 이용하여 서버에 접속하고 데이터 수신용 스레드를 실행하여 수신된 데이터를 처리하고 사용자의 입력을 받아 서버로 전송하는 역활을 담당합니다.

RecieveDataThread : 서버에서 수신된 데이터를 콘셀에 출력하는 일을 담당합니다.


ChatServer.java

import java.net.*;

import java.io.*;

import java.util.*;


class  ChatServer

{

protected final int port = 6000;

ServerSocket server = null;

Socket child = null;


HashMap<String, PrintWriter> hm;


public ChatServer() {

ChatSverThread sr;

Thread t;


try {

server = new ServerSocket( port );

System.out.println( "************** 채팅 서버 ***********" );

System.out.println( "클라이언트의 접속을 기다립니다." );


hm = new HashMap<String, PrintWriter>();


while( true ) {

child = server.accept();

if( child != null ) {

sr = new ChatSverThread( child, hm );

t = new Thread( sr );

t.start();

}

}

}

catch ( Exception e ) {

e.printStackTrace();

}

}


public static void main(String[] args) 

{

new ChatServer();

}

}


ChatServerThread.java

import java.net.*;

import java.io.*;

import java.util.*;


public class ChatSverThread implements Runnable

{

Socket child;


BufferedReader ois;

PrintWriter oos;

String user_id;

HashMap<String, PrintWriter> hm;

InetAddress ip;

String msg;


public ChatSverThread( Socket s, HashMap<String, PrintWriter> h ) {

child = s;

hm = h;


try {

ois = new BufferedReader( new InputStreamReader( child.getInputStream() ) );

oos = new PrintWriter( child.getOutputStream() );


user_id = ois.readLine();

ip = child.getInetAddress();

System.out.println( ip + "로부터 " + user_id + "님이 접속하였습니다." );

broadcast(user_id + "님이 접속하셨습니다.");


synchronized( hm ) {

hm.put( user_id, oos );

}

}

catch (Exception e ) {

e.printStackTrace();

}

}


public void run() {

String receiveData;


try

{

while( (receiveData = ois.readLine()) != null ) {


if( receiveData.equals( "/quit" ) ) {

synchronized( hm ) {

hm.remove( user_id );

}

break;

}

else if( receiveData.indexOf( "/to" ) >= 0 ) {

sendMsg( receiveData );

}

else broadcast( user_id + " >> " + receiveData );

}

}

catch (Exception e ) {

e.printStackTrace();

}

finally {

synchronized( hm ) {

hm.remove( user_id );

}

broadcast( user_id + "님이 퇴장했습니다." );

System.out.println( user_id + "님이 퇴장했습니다." );

try

{

if( child != null ) {

ois.close();

oos.close();

child.close();

}

}

catch ( Exception e) {}

}

}


public void broadcast(String message){

synchronized( hm ) {

try{

for( PrintWriter oos : hm.values( )){

 oos.println( message );

 oos.flush();

}

}catch(Exception e){ }

}

}


public void sendMsg(String message){

int begin = message.indexOf(" ") + 1;

int end   = message.indexOf(" ", begin);


if(end != -1){

String id = message.substring(begin, end);

String msg = message.substring(end+1);

PrintWriter oos = hm.get(id);

try{

if(oos != null){

oos.println( user_id + "님이 다음과 같은 귀속말을 보내셨습니다. : " + msg );

oos.flush();

}

}catch(Exception e){ }

}

}

}


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

public class  ChatClient {
String ipAddress;
static final int port=6000;
Socket client=null;
BufferedReader read;
PrintWriter oos;
BufferedReader ois; 
String sendData;
String receiveData;

String user_id;
ReceiveDataThread rt;
boolean endflag=false;

public ChatClient(String id, String ip) {
user_id=id;
ipAddress=ip;
try{
System.out.println("**** 클라이언트*****");
client = new Socket(ipAddress, port); 

read= new BufferedReader(new InputStreamReader(System.in));
ois = new BufferedReader( new InputStreamReader( client.getInputStream() ) );
oos = new PrintWriter( client.getOutputStream() );

oos.println( user_id );
oos.flush();            

rt= new ReceiveDataThread(client, ois);
Thread t = new Thread(rt);
t.start(); 

while(true){
sendData = read.readLine();

oos.println( sendData );
oos.flush();            

if(sendData.equals( "/quit") ) { 
endflag = true;
break;
}
}
System.out.print("클라이트의 접속을 종료합니다. ");
System.exit( 0 );
} catch(Exception e){  
if(!endflag) e.printStackTrace();
}
finally{
try{
ois.close();
oos.close();
client.close();   
System.exit(0);
}catch(IOException e2){
e2.printStackTrace();
}
}
}

public static void main(String[] args) {
if(args.length < 2) {
System.out.print("USAGE : java  ChatClient  사용자_id  서버_ip");
System.exit(0);
}
new ChatClient(args[0], args[1]);
}
}


RecieveDataThread.java

import java.net.*;

import java.io.*;


class ReceiveDataThread implements Runnable{

Socket client;

BufferedReader ois;

String receiveData;


public ReceiveDataThread(Socket s, BufferedReader ois){ 

client = s;

this.ois = ois;

}

  

  public void run(){

try{

while( ( receiveData = ois.readLine() ) != null ) System.out.println( receiveData );

}catch(Exception e){  

e.printStackTrace();  

    }

    finally{

try{

ois.close();

client.close();  

}catch(IOException e2){

e2.printStackTrace();

}

    }

  }

}



'프로그래밍 > JAVA' 카테고리의 다른 글

폭탄 퍼즐 게임  (0) 2012.10.31
JDBC와 MySQL을 이용한 데이터베이스 엑세스  (0) 2012.10.20
간단한 이미지 뷰어  (0) 2012.09.28
자바 수업용 예제 및 파워포인트  (0) 2012.07.18