반응형
Notice
Recent Posts
Recent Comments
관리 메뉴

꿈꾸는 사람.

[안드로이드 소켓통신] 클라이언트 소켓 앱에, 서버 소켓 커널 드라이버로 (1편) 본문

IT/Android

[안드로이드 소켓통신] 클라이언트 소켓 앱에, 서버 소켓 커널 드라이버로 (1편)

현무랑 니니 2014. 8. 23. 03:27
반응형










안드로이드 기기 개발을 할 경우 앱이나 프레임웍에서 하드웨어를 제어하거나 정보를 읽는 기능이 요구된다.

이를 간단하게 구현할 수 있는 방법으로 소켓 통신을 이용하는 것이다.

소켓 통신은 기기간이나 클라이언트/서버가 다른 기기에 있는 경우에 개발하지만 한 기기에 있는 경우에는 특수한 소켓을 이용해야 한다.

이번 글은 단일 기기 내에서 소켓 통신에 대한 내용이다.



1. 소켓 통신  개요.

기기간 소켓 통신


개인 컴퓨터나 스마트폰에서 클라이언트 소켓을 만들고 서버(포탈, 검색)에 요청을 한다.

서버 컴퓨터에 서버 소켓을 생성하고 고객의 요청을 받고 응답한다.


안드로이드 단일 기기 내 소켓 통신

앱에서 하위 커널 레벨의 드라이버와 소켓 통신을 하는 경우이다.

앱에는 클라이언트 소켓을 만들고 커널에 서버 소켓을 만든다.

앱은 소켓을 통해 하드웨어 상태 정보를 읽거나 설정을 변경할 수 있다.

(클라이언트/서버 모두 앱 레벨에서 만드는 것이 아니다.)



2. 단일 기기 내  앱 - 커널 간 소켓 통신


문제점

1. 안드로이드 앱은 JAVA로 커널 드라이버는 C 언어로 되어 있다. 엔디안이 다르다.

2. 단일 기기 내 소켓 통신이므로 TCP 소켓은 적절하지 않다.


해결책

1. 엔디안 변환을 한다. 서버쪽 보다 클라이언트에서 변환하는 것을 추천한다.

 JAVA

 C, C++

 Big endian

 Little endian


2. 유닉스 도메인(AF_LOCAL) 소켓을 사용한다.

 클래스

 TCP 소켓

 유닉스 도메인 소켓

 서버 소켓

 ServerSocket

 LocalServerSocket

 클라이언트 소켓

 Socket

 LocalSocket

 소켓 주소

 SocketAddressL

 LocalSocketAddress


3. LocalSocket 클라이언트 예

소켓 주소 설정

주의할 점은 꼭 Namespace를 설정해 주어야 한다.

 new LocalSocketAddress(SOCKET_ADDRESS, Namespace.FILESYSTEM)


소켓 생성 후 연결

연결할 때 소켓 주소를 패러미터로 넘겨준다.

 생성:  new LocalSocket();

 연결:  connect(endpoint);


소켓 종료

데이터 송수신이 끝나면 종료한다.

 close()


데이터 송신

 getOutputStream().write(buffer, offset, count)


전체 클라이언트소켓 코드

파일 - MyLocalSocket.java

package com.hyunmu.mylocalsocket;


import java.io.IOException;

import android.net.LocalSocket;

import android.net.LocalSocketAddress;

import android.net.LocalSocketAddress.Namespace;


public class MyLocalSocket {

static final String TAG = "MyLocalSocket";

private static MyLocalSocket mMyLocalSocket = null;

public static String SOCKET_ADDRESS ="/dev/socket/serversocket"; // assumes it exist.

private static LocalSocket mLocalSocket = null;

private LocalSocketAddress mLocalSocketAddress = null;

public static MyLocalSocket getInstance() {

if (mMyLocalSocket == null) {

mMyLocalSocket = new MyLocalSocket();

}

return mMyLocalSocket;

}

private boolean openLocalSocket() {

if (mLocalSocket == null) {

mLocalSocket = new LocalSocket();

return true;

}

return false;

}

private boolean connectLocalSocket(LocalSocketAddress endpoint) {

if (!mLocalSocket.isConnected()) {

mLocalSocket.connect(endpoint);

return true;

}


return true;

}

private boolean setup() {

openLocalSocket();

if (connectLocalSocket(mLocalSocketAddress)) {

return true;

}

else {

return false;

}

}

public void sendData(byte[] data, int offset, int count) {

boolean bSetup = setup();

if (bSetup) {

mLocalSocket.getOutputStream().write(data, offset, count);

mLocalSocket.getOutputStream().flush();

}

}

}


반응형
Comments