이번 강좌에는 Multi-Thread Echo Client, Server에 대해 알아 보도록 하겠습니다. 이전 강좌의 끝 부분에 제가 여러분들께 생각해 보시라고 했던 부분이 있을 겁니다. 여러대의 클라이언트가 서버에 접속을 해오는 경우 이전의 예제 같은경우 두번째 클라이언트의 연결 부터 연결은 블로킹(대기)되게 되는데 이를 해결 하는 방법은 멀티쓰레드를 이용하는 겁니다. 오늘은 그부분에 대해 배워 보도록 하겠습니다. 자~~~~ 갑니다.
이전 예제인 EchoServer 의 경우 동시에 여러 개의 클라이언트를 처리하는데 있어서는 read 메소드의 Blocking 으로 인해 어려움이 있습니다. 즉 동시에 여러 클라이언트의 요구를 처리 하지 못한다는거죠... 이문제를 해결하기 위해 다중 스레딩 (Multi-Threading) 을 구현한 서버를 사용하는 것인데 다중 스레드 서버는 클라이언트가 접속 할때 마다 1 개 이상의 스레드를 만들어 돌리기 때문에 결국 블록킹 I/O 문제를 해결해 주는 것 입니다. 즉 메인 스레드는 클라이언트의 연결을 받기만 하고 클라이언트와 데이터를 주고 받는 일은 별도의 Thread 에서 처리 하도록 구성을 하는 겁니다.
[ MultiThreadEchoServer.java] -- 서버이니까 실행시 포트 번호만 인자로 주세요... java MultiThreadEchoServer 1000
import java.io.*;
import java.net.*;
import java.net.*;
class MultiThreadEchoServer extends Thread {
protected Socket sock;
//----------------------- Constructor
MultiThreadEchoServer (Socket sock) {
this.sock = sock;
}
protected Socket sock;
//----------------------- Constructor
MultiThreadEchoServer (Socket sock) {
this.sock = sock;
}
//------------------------------------
public void run() {
try {
System.out.println(sock + ": 연결됨");
InputStream fromClient = sock.getInputStream();
OutputStream toClient = sock.getOutputStream();
byte[] buf = new byte[1024];
int count;
while( (count = fromClient.read(buf)) != -1 ) {
toClient.write( buf, 0, count );
System.out.write(buf, 0, count);
}
toClient.close();
System.out.println(sock + ": 연결 종료");
}
catch( IOException ex ) {
System.out.println(sock + ": 연결 종료 (" + ex + ")");
}
finally {
try {
if ( sock != null ) sock.close();
}
catch( IOException ex ) {}
}
}
public void run() {
try {
System.out.println(sock + ": 연결됨");
InputStream fromClient = sock.getInputStream();
OutputStream toClient = sock.getOutputStream();
byte[] buf = new byte[1024];
int count;
while( (count = fromClient.read(buf)) != -1 ) {
toClient.write( buf, 0, count );
System.out.write(buf, 0, count);
}
toClient.close();
System.out.println(sock + ": 연결 종료");
}
catch( IOException ex ) {
System.out.println(sock + ": 연결 종료 (" + ex + ")");
}
finally {
try {
if ( sock != null ) sock.close();
}
catch( IOException ex ) {}
}
}
//------------------------------------
public static void main( String[] args ) throws IOException {
ServerSocket serverSock = new ServerSocket( Integer.parseInt(args[0]) );
System.out.println(serverSock + ": 서버 소켓 생성");
while(true) {
Socket client = serverSock.accept();
MultiThreadEchoServer myServer = new MultiThreadEchoServer(client);
myServer.start();
}
}
}
public static void main( String[] args ) throws IOException {
ServerSocket serverSock = new ServerSocket( Integer.parseInt(args[0]) );
System.out.println(serverSock + ": 서버 소켓 생성");
while(true) {
Socket client = serverSock.accept();
MultiThreadEchoServer myServer = new MultiThreadEchoServer(client);
myServer.start();
}
}
}
클라이언트 프로그램은 이전 강좌의 EchoClient.java와 동일 합니다.
[EchoClient.java] //클라이언트 이므로 실행시 서버, 포크번호 2개를 인자로 줍니다. java EchoClient 1000
import java.io.*;
import java.net.*;
import java.net.*;
class EchoClient
{ public static void main( String[] args )
throws IOException
{
Socket sock = null;
try
{
sock = new Socket(args[0], Integer.parseInt(args[1]));
System.out.println(sock + ": 연결됨");
OutputStream toServer = sock.getOutputStream();
InputStream fromServer = sock.getInputStream();
{ public static void main( String[] args )
throws IOException
{
Socket sock = null;
try
{
sock = new Socket(args[0], Integer.parseInt(args[1]));
System.out.println(sock + ": 연결됨");
OutputStream toServer = sock.getOutputStream();
InputStream fromServer = sock.getInputStream();
byte[] buf = new byte[1024];
int count;
while( (count = System.in.read(buf)) != -1 )
{
toServer.write( buf, 0, count );
count = fromServer.read( buf );
System.out.write( buf, 0, count );
}
toServer.close();
while((count = fromServer.read(buf)) != -1 )
System.out.write( buf, 0, count );
System.out.close();
System.out.println(sock + ": 연결 종료");
} catch( IOException ex )
int count;
while( (count = System.in.read(buf)) != -1 )
{
toServer.write( buf, 0, count );
count = fromServer.read( buf );
System.out.write( buf, 0, count );
}
toServer.close();
while((count = fromServer.read(buf)) != -1 )
System.out.write( buf, 0, count );
System.out.close();
System.out.println(sock + ": 연결 종료");
} catch( IOException ex )
{
System.out.println("연결 종료 (" + ex + ")");
} finally
{
try
{
if ( sock != null )
sock.close();
} catch( IOException ex ) {}
}
}
}
System.out.println("연결 종료 (" + ex + ")");
} finally
{
try
{
if ( sock != null )
sock.close();
} catch( IOException ex ) {}
}
}
}
[결과]
위는 MultiThreadEchoServer 실행 화면
클라이언트1
클라이언트2
이번 강좌는 여기까지 하도록 하겠습니다. 그럼 다은 강좌에서 뵙도록 하겠습니다.
감사합니다~
댓글 없음:
댓글 쓰기