검색결과 리스트
글
[JAVA] 같은 공유기에 접속중인 기기의 IP 주소 확인하는방법
TCP를 통해 Socket 통신을 하기 위해서는 접속하고자 하는 기기에 할당된 IP주소를 알고 있어야 합니다. 다시 말하자면, IP 주소를 알지 못할 경우 TCP를 통해서는 기기간의 통신이 불가능하다는 것입니다.
그렇다면 상대의 IP 주소를 알아낼 수 있는 방법은 없는 것일까요? IP 프로토콜 규약에 의하면 특수 IP 주소를 사용하면 다른 기기와 통신이 가능하도록 설정되어 있습니다. 예를 들어 '255.255.255.255' 주소로 패킷을 보내면 같은 라우터(공유기) 내에 연결된 모든 기기들이 이를 수신하게 됩니다. 이를 Broadcast라고 칭하며 이를 사용하기 위해서는 TCP가 아닌 UDP 방식을 사용하여야 합니다.
아래의 소스코드는 UDP 방식을 사용하여 서버가 IP주소 '255.255.255.255'를 통해 같은 라우터(공유기) 내에 접속중인 기기들에게 패킷을 보낸 후 이를 수신한 기기가 자신의 IP 주소를 서버에 알려주는 방식입니다.
- DatagramPacket가 상대에게 전송될 때 해당 패킷 안에는 패킷을 보낸 측의 IP 주소가 담겨 있습니다. 이를 통해 서버측 IP와 클라이언트측 IP를 서로 알 수 있습니다.
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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 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; import java.net.UnknownHostException; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub RecvServer rm = new RecvServer(); rm.start(); for (int i = 0; i < 10; i++) { try { new SearchDevice("255.255.255.255", 8200).start(); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } rm.closeServer(); } static class SearchDevice extends Thread { InetAddress ia; int port; SearchDevice(String IPaddr, int Port) { try { ia = InetAddress.getByName(IPaddr); port = Port; } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run() { String msg = "Hello, ELECS!"; try { DatagramSocket ds = new DatagramSocket(); int length = msg.length(); byte[] msgbyte = msg.getBytes(); DatagramPacket dp = new DatagramPacket(msgbyte, length, ia, port); ds.send(dp); ds.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } static class RecvServer extends Thread { String text; String clientIp; DatagramPacket dp; DatagramSocket ds; Object lock = new Object(); public void closeServer() { synchronized (lock) { ds.close(); } } public void run() { int port = 8000; byte[] message = new byte[1000]; dp = new DatagramPacket(message, message.length); try { ds = new DatagramSocket(port); ds.receive(dp); synchronized (lock) { text = new String(message, 0, dp.getLength()); ds.close(); clientIp = dp.getAddress().getHostAddress(); System.out.println("Client IP : " + clientIp); } } catch (Exception e) { e.printStackTrace(); } } } } | cs |
Client측
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 | 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; import java.net.UnknownHostException; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub String text; String serverIp; DatagramPacket dp; int port = 8200; byte[] message = new byte[1000]; dp = new DatagramPacket(message, message.length); try { DatagramSocket ds = new DatagramSocket(port); ds.receive(dp); text = new String(message, 0, dp.getLength()); ds.close(); serverIp = dp.getAddress().getHostAddress(); new SearchDevice(serverIp, 8000).start(); } catch (Exception e) { e.printStackTrace(); } } static class SearchDevice extends Thread { InetAddress ia; int port; SearchDevice(String IPaddr, int Port) { try { ia = InetAddress.getByName(IPaddr); port = Port; } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run() { String msg = "Hello, ELECS!"; try { DatagramSocket ds = new DatagramSocket(); int length = msg.length(); byte[] msgbyte = msg.getBytes(); DatagramPacket dp = new DatagramPacket(msgbyte, length, ia, port); ds.send(dp); ds.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } | cs |
결과
'프로그래밍 팁' 카테고리의 다른 글
| Fedora에 이전 버전의 OpenJDK 설치하기(Install OpenJDK 7 in Fedora 23) (0) | 2015.12.22 |
|---|---|
| OpenCV 최신 버전에서 Python으로 SIFT, SURF 사용하기(Install OpenCV 3.0 in Ubuntu) (2) | 2015.11.18 |
| [JAVA] Socket 서버 구현시 안전하게 SocketServer를 종료하는 방법 (3) | 2015.10.14 |
| [C/C++]thread 조건변수 다루기 - pthread_cond_broadcast() (0) | 2015.09.01 |
| [JAVA]JDWP(Java™ Debug Wire Protocol) (0) | 2015.08.21 |
설정
트랙백
댓글
글
[JAVA] Socket 서버 구현시 안전하게 SocketServer를 종료하는 방법
안드로이드를 활용한 다양한 소켓 프로그래밍들의 에제를 둘러보다 보면 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 |
'프로그래밍 팁' 카테고리의 다른 글
| 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 |
설정
트랙백
댓글
글
[컴퓨터비전]이미지 변환시 DoF(Degrees of Freedom)에 대한 고찰
영상처리와 컴퓨터비전 분야에서 가장 중요한 요소로 Matrix 변환을 기반으로 하는 선형대수(Linear Algebra)가 있습니다. 특히 화면에 나타나는 이미지를 변환할 때 (Geometric Transformations를 하기 위해 사용되는 행렬), DoF라는 개념이 언급됩니다. 본 포스팅에서는 이 DoF에 대해 이야기해 보려 합니다.
-DoF(Degrees of Freedom)이란?
DoF(Degrees of Freedom), 우리말로 '자유도'라 일컫는 요소로 이미지가 변환이 될 때 최소한으로 필요로 하는 독립변수의 수라고 정의할 수 있습니다. 이에 대해 각 Geometric Transformations들을 통해 알아보도록 하겠습니다.
-Translation
이미지 변환중 가장 단순하다고 할 수 있는 변환 중 하나입니다. 이를 Matrix로 나타내면 다음과 같습니다.
위의 식에서 보이는 바와 같이 총 2개의 변수에 의해 이미지가 변환되고 있는 것을 알 수 있습니다. 각 변수는 이미지의 x축과 y축을 이동하는 식으로서 이는 Translation의 DoF가 2임을 알 수 있습니다.
또한 Translation의 결과물은 원본 이미지에서 큰 변화가 일어나지 않습니다.
-Rigid(Euclidean)
위에서 보았던 Translation을 수행한 후 이미지를 일정 각도로 회전시킨 결과입니다. 이를 Matrix로 나타내면 다음과 같습니다.
위의 식에서 보는 바와 같이 x축으로의 이동, y축으로의 이동, 회전각도 Θ로 DoF는 3임을 알 수 있습니다.
위 Rigid의 최종 결과물은 원본 이미지의 높이 및 너비와 같은 길이가 보존되는 것을 알 수 있습니다.
-Similiary
위의 Rigid Transform에서 결과물의 사진 크기가 변하였음을 확인할 수 있습니다. 이를 Matrix로 나타내면 다음과 같습니다.
위의 식에서 보는 바와 같이 x축으로의 이동, y축으로의 이동, 회전각Θ, 크기변수s 로 DoF는 4임을 알 수 있습니다.
위 Similary의 최종 결과물은 원본 이미지의 직각 부분이 유지되는 것을 알 수 있습니다.
-Affine
원본 이미지에 Affine Matrix가 적용되면 이미지가 위에서 보는 바와 같이 일그러진 모습을 하고 있는 것을 보실 수 있습니다. 이를 Matrix로 나타내면 다음과 같습니다.
Affine Matrix의 DoF는 6임을 확인하실 수 있습니다.
위 Affine의 최종 결과물은 원본 이미지의 두 변의 평행이 보존됨을 확인하실 수 있습니다.
-Projective
원본이미지에 Projectiive가 젹용되면 마치 이미지가 정사영에 투영된 듯이 이미지를 기울여서 보는 듯한 느낌이 들 겁니다. 이를 Matirx로 나타내면 다음과 같습니다.
Projective Matrix의 DoF는 8임을 알 수 있습니다.
위 Projective의 최종 결과물은 원본 이미지의 특정 두 변의 평행이 유지되는 것을 알 수 있습니다.
'공대생의 팁' 카테고리의 다른 글
| File System 및 커널 수정을 gedit로 쉽게 하는 방법(sudo root 권한으로 gedit 실행) (0) | 2015.11.16 |
|---|---|
| 우분투 커널 업데이트 후 VirtualBox가 제대로 동작되지 않을 때 해결방법(버전 5.08 이후) (0) | 2015.11.05 |
| IP v4 주소 0.0.0.0의 의미 (0) | 2015.09.27 |
| PHLASHNT.SYS 드라이버를 로드할 수 없습니다. 오류 코드: 1275 (1) | 2015.09.07 |
| Intel Management Engine BIOS Extention 설정시 암호 변경이 안될 때 해결방법 (1) | 2015.08.19 |
