문제
서버와 클라이언트가 멀티스레드를 바탕으로 순서에 상관없이 자유롭게 대화할 수 있는 채팅 문제입니다 이를 해결하는 프로그램의 다음 실행상태에 대해 빈칸을 채우세요
프로그램의 실행순서 및 실행상태
①
②
1 public static void main(String[] args) {
2 new ChatNetwork();
CN1b public ChatNetwork() {
[Server]님이 들어오셨습니다. 대화(종료시 quit)를 입력하세요
[Client]님이 들어오실때까지 잠시만 기다려주세요
CN12 new Network();
N1b public Network() {
N1e }
CN11 network =
CN13 network.connectAsServer( this );
N2b public void connectAsServer( Runnable obj ) {
N22 serverSocket.accept();
E001 // 클라이언트에서 네트워크 연결 요청
N21 socket =
N23 connectInOut( obj );
N4b public void connectInOut( Runnable obj ) {
N41 waitForCounterpart.start();
CN4b public void run() {
CN42 network.read() ) != null; ) {
N5b public String read() {
N52 in.readLine();
E002 // 클라이언트 데이터가 도착할 때까지 계속 대기
E003 // (수신전용스레드와 별개로) 메인 스레드 N41 이후 실행중
N4e }
N2e }
[Client]님이 들어오셨습니다
CN14 this.write( "[Server]" );
CN3b public void write( String id ) {
CN32 scan.nextLine() ) != null; ) {
E004 // 대화를 입력할 때까지 계속 대기
E005 // 클라이언트에서 보낸 데이터([Client]안녕하세요) 도착
③
N51 return
N5e }
CN41 for ( String message = null; ( message =
CN45 System.out.println( message );
[Client]안녕하세요
CN46 }
CN42 network.read() ) != null; ) {
N5b public String read() {
N52 in.readLine();
E002 // 클라이언트 데이터가 도착할 때까지 계속 대기
E006 // '반갑습니다' 입력
반갑습니다
④
CN31 for ( String message = null; ( message =
CN35 network.write( id + message );
N6b public void write( String data ) {
N61 out.println( data );
N6e }
CN36 }
CN32 scan.nextLine() ) != null; ) {
E004 // 대화를 입력할 때까지 계속 대기
E007 // 클라이언트에서 보낸 데이터([Client]quit) 도착
⑤
N51 return
N5e }
CN41 for ( String message = null; ( message =
[Client]님이 나가셨습니다
CN43 network.write( message );
N6b public void write( String data ) {
N61 out.println( data );
N6e }
CN44 break;
CN47 network.close();
N7b public void close() {
N7e }
CN4e }
E008 // 'quit' 입력
quit
CN31 for ( String message = null; ( message =
[Server]님이 나가셨습니다
CN33 network.write( id + message );
N6b public void write( String data ) {
N6e }
CN34 break;
CN3e }
CN1e }
3 }
E009 // 메인스레드와 수신전용스레드가 모두 종료하여 프로그램 종료
프로그램 코드
E001 // 클라이언트에서 네트워크 연결 요청
E002 // 클라이언트 데이터가 도착할 때까지 계속 대기
E003 // (수신전용스레드와 별개로) 메인 스레드 N41 이후 실행중
E004 // 대화를 입력할 때까지 계속 대기
E005 // 클라이언트에서 보낸 데이터([Client]안녕하세요) 도착
E006 // '반갑습니다' 입력
E007 // 클라이언트에서 보낸 데이터([Client]quit) 도착
E008 // 'quit' 입력
E009 // 메인스레드와 수신전용스레드가 모두 종료하여 프로그램 종료
import chat.ChatNetwork;
public class MultiThreadChatServer
{
1 public static void main(String[] args) {
2 new ChatNetwork();
3 }
}
package chat;
import java.util.Scanner;
import network.Network;
public class ChatNetwork implements Runnable
{
private Network network;
CN1b public ChatNetwork() {
System.out.println( "[Server]님이 들어오셨습니다. 대화(종료시 quit)를 입력하세요" );
System.out.println( "[Client]님이 들어오실때까지 잠시만 기다려주세요" );
CN11 network =
CN12 new Network();
CN13 network.connectAsServer( this );
network.write( "[Server]님이 들어오셨습니다" );
CN14 this.write( "[Server]" );
CN1e }
CN2b public ChatNetwork( String serverIP ) {
System.out.println( "[Client]님이 들어오셨습니다. 대화(종료시 quit)를 입력하세요" );
CN21 network =
CN22 new Network();
CN23 network.connectAsClient( serverIP, this );
network.write( "[Client]님이 들어오셨습니다" );
CN24 this.write( "[Client]" );
CN2e }
CN3b public void write( String id ) {
try {
Scanner scan = new Scanner( System.in );
CN31 for ( String message = null; ( message =
CN32 scan.nextLine() ) != null; ) {
if( message.contains( "quit" ) ) {
System.out.println( id + "님이 나가셨습니다" );
network.write( id + "님이 나가셨습니다" );
CN33 network.write( id + message );
CN34 break;
}
CN35 network.write( id + message );
CN36 }
scan.close();
} catch ( Exception e ) {
e.printStackTrace();
}
CN3e }
@Override
CN4b public void run() {
CN41 for ( String message = null; ( message =
CN42 network.read() ) != null; ) {
if( message.contains( "quit" ) ) {
System.out.println( message );
CN43 network.write( message );
CN44 break;
}
else {
CN45 System.out.println( message );
}
CN46 }
CN47 network.close();
CN4e }
}
package network;
import java.io.*;
import java.net.*;
public class Network
{
public static final int serverPort = 7700;
protected ServerSocket serverSocket;
protected Socket socket;
private BufferedReader in;
private PrintWriter out;
private Thread waitForCounterpart;
N1b public Network() {
serverSocket = null;
socket = null;
in = null;
out = null;
waitForCounterpart = null;
N1e }
N2b public void connectAsServer( Runnable obj ) {
try {
serverSocket = new ServerSocket( serverPort );
N21 socket =
N22 serverSocket.accept();
N23 connectInOut( obj );
} catch ( Exception e ) {
e.printStackTrace();
}
N2e }
N3b public void connectAsClient( String serverIP, Runnable obj ) {
try {
N31 socket =
N32 new Socket( serverIP, serverPort );
N33 connectInOut( obj );
} catch ( Exception e ) {
e.printStackTrace();
}
N3e }
N4b public void connectInOut( Runnable obj ) {
try {
in = new BufferedReader( new InputStreamReader( socket.getInputStream() ));
out = new PrintWriter( socket.getOutputStream(), true );
waitForCounterpart = new Thread( obj );
N41 waitForCounterpart.start();
} catch ( Exception e ) {
e.printStackTrace();
}
N4e }
N5b public String read() {
try {
if ( this.isConnecting() == true )
N51 return
N52 in.readLine();
} catch ( Exception e ) {
e.printStackTrace();
}
return null;
N5e }
N6b public void write( String data ) {
try {
if ( this.isConnecting() == true )
N61 out.println( data );
} catch ( Exception e ) {
e.printStackTrace();
}
N6e }
public boolean isConnecting() {
if ( ( socket != null )
&& ( in != null )
&& ( out != null )
&& ( waitForCounterpart != null )
&& ( waitForCounterpart.getState() != Thread.State.TERMINATED ) )
return true;
else
return false;
}
N7b public void close() {
try {
if ( waitForCounterpart != null ) {
waitForCounterpart.interrupt();
waitForCounterpart = null;
}
if ( in != null ) {
in.close();
in=null;
}
if ( out != null ) {
out.flush();
out.close();
out = null;
}
if ( socket != null ) {
socket.close();
socket = null;
}
if ( serverSocket != null ) {
serverSocket.close();
serverSocket = null;
}
} catch ( Exception e ) {
e.printStackTrace();
}
N7e }
}