검색결과 리스트
글
[JAVA] Socket 서버 구현시 안전하게 SocketServer를 종료하는 방법
프로그래밍 팁
2015. 10. 14. 23:18
안드로이드를 활용한 다양한 소켓 프로그래밍들의 에제를 둘러보다 보면 Server 측의 Socket을 다루는 데 종종 난해한 경우가 있습니다. 가령 Client측으로부터 Socket 통신이 한창 진행중인 상황에서 서버측 Socket을 닫아버리면 진행중이던 통신 관련 작업이 모두 끝나기도 전에 서버가 종료되어 버리는 심각한 상황이 발생할 수도 있는 것이지요.
본 포스팅에서는 Java를 활용한 서버측의 Socket을 좀 더 안정적으로 종료시키는 방법에 대해 알아보도록 하겠습니다.
- Client와 Socket 통신이 진행중인 상황에서 ServerSocket이 강제로 종료되지 않도록 하기 위해 synchronized를 사용합니다. 이는 C/C++에서 제공하는 Mutex와 유사한 역할을 합니다. synchronized() 의 인자(Argument)를 가지고 있는 쪽에서 실행을 하다가 종료가 되었을 때 이를 다른 쪽에서 점유한 후 실행이 종료될 때 까지 다른 부분에서는 실행되지 않도록 설정합니다.
- ServerSocket이 accpt()를 실행하던 중에 종료되었을 때 SocketException이 발생합니다. 이 때 try-catch를 통해 해당 Exception을 catch한 후 Server가 안전하게 종료되었음을 확인합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub RecvMessage rm = new RecvMessage(); //Server Thread를 실행합니다. rm.start(); .... //ServerSocket를 닫음으로서 Server Thread를 종료합니다. rm.closeServer(); } static class RecvMessage extends Thread { boolean ready = true; Socket socket; InputStream is; ObjectInputStream ois; String clientIp; ServerSocket sockserver; //Mutex로 사용할 Object 변수를 선언합니다. Object lock = new Object(); public void closeServer() { try { //Client와 Socket 통신이 진행중일 경우 종료될 때까지 기다립니다. synchronized (lock) { sockserver.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run() { try { sockserver = new ServerSocket(8200); while (ready) { socket = sockserver.accept(); //Client와의 통신이 종료될 때 까지 SocketServer의 종료를 보류시킵니다. synchronized (lock) { is = socket.getInputStream(); ois = new ObjectInputStream(is); clientIp = (String) ois.readObject(); System.out.println("Client IP : " + clientIp); ois.close(); is.close(); socket.close(); } } } catch (SocketException e) { //ServerSocket가 종료되었을 때 실행됩니다. System.out.println("ServerSocket is closed!"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } | cs |
300x250
'프로그래밍 팁' 카테고리의 다른 글
OpenCV 최신 버전에서 Python으로 SIFT, SURF 사용하기(Install OpenCV 3.0 in Ubuntu) (2) | 2015.11.18 |
---|---|
[JAVA] 같은 공유기에 접속중인 기기의 IP 주소 확인하는방법 (0) | 2015.10.15 |
[C/C++]thread 조건변수 다루기 - pthread_cond_broadcast() (0) | 2015.09.01 |
[JAVA]JDWP(Java™ Debug Wire Protocol) (0) | 2015.08.21 |
[Java] Error 혹은 Debug시 등장하는 method인 access$000 (0) | 2015.08.20 |