소켓 생성
socket( ${family}, SOCK_RAW, ${protocol});

family : IPv4 - AF_INET
          IPv6 - AF_INET6

protocol : /usr/include/netinet/in.h 참조


protocol을 IPPROTO_RAW를 사용할 경우 ip헤더도 직접 조작하여 패킷을 전송할 수 있다.

IPv4에서는 ip헤더를 직접 조작한다는 옵션을 필히 주어야 한다.

int on = 1;
...
setsockopt( raw_socket, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on) );


IPv4에서는 IPPROTO_RAW로 생성한 소켓끼리 통신이 가능하다.
IPv6에서는 IPPROTO_RAW로 생성한 소켓을 전송할 때 받는 쪽에서는 전송하는 패킷의 페이로드에 해당하는 protocol로 생성한 소켓이어야 받을 수 있다.

http://naradesign.net


웹 표준에 대해 잘 설명해놓으신거 같다.

'develop > 공통' 카테고리의 다른 글

DualStack Mobile IPv6 with Multiple Care of Address  (0) 2013.06.24
IPv4, IPv6 체크 정규식  (0) 2013.04.02
HTML5 변경 점  (0) 2012.11.26
C++ Operator Precedence  (0) 2010.02.23
유니코드 한글 음절들  (0) 2010.02.22

출처 : http://cdkkcdkktoandroid.tistory.com/14


저도 아직 자세히는 파악을 하지 못했지만 WebView.java를 보니깐 WebView로 url를 로드 하면 로드 할때마다 쿠키를 사용하지 못하더군요. 아 사용 못하는게 아니고 대략 테스트를 해보니 로드된 페이지에서 쿠키를 저장하고 있는데 약 5분 정도가 지나야 WebView에서도 적용이 되더군요. 이상해서 WebView를 까보니 WebView로 로드 하게되면 로드 될때마다 쿠키를 초기화 하더군요. 

이를 해결하기 위해서는  CookieSyncManager를 사용해야 합니다.

액티비티를 호출하게 되면 그 생명주기에 맞게 Override한 메소드를 타게 되어있는데 그에 맞게 CookieSyncManager를 사용하면 WebView로 띄운 Url의 쿠키를 어플에 바로 적용이 되더군요

  @Override 

    public void onStart() { 

        super.onStart(); 

        CookieSyncManager.createInstance(this);

    }   

액티비티가 호출되면 onStart 메소드를 타는데 이때  인스턴스를 생성하고

@Override

    public void onResume(){

     super.onResume();

     CookieSyncManager.getInstance().startSync();

    }

액티비티가 상호작용이 이루지면 onResume 메소드를 거칩니다. 이때 생성한 인스턴스를 

startSync() 해줍니다.


그리고 액티비티가 종료될 수 도 있는 상태인 일시정지 상태(종료되는건 아님)에 stopSync() 해줍니다.

 @Override

    public void onPause(){

     super.onPause();

     CookieSyncManager.getInstance().stopSync();

    }

이렇게 해놓으면 액티비티 생명주기에 따라 쿠키를 동기화 시켜주게 됩니다.

그리고 하나더 중요한 부분이

 WebView를 띄울때 브라우저에서 제어권을 넘겨 받는 부분인 setWebViewClient의 페이지 로딩이 끝나면 타는 메소드인 onPageFinished 안에 쿠키를 분석해놔야 합니다.

webView.setWebViewClient(new MyWebClient{

        public boolean shouldOverrideUrlLoading(WebView view, String url){

     view.loadUrl(url);

     return true;

     }

   

     //WebView가 로딩이 끝나면 시작

     public void onPageFinished(WebView view, String url){

     CookieSyncManager.getInstance().sync();

     }

        });

참고로 말씀들이면 이 방법이 틀렸을 수도 있습니다. 한동안 WebView로 해당 URL의 쿠키를 사용할 수 있게 하기 위해서 별짓을 다 해봤는데 이 방법으로 하니 잘 되더군요.

그리고 구지 이 방법으로 하지 않아도 됩니다. 웹서버에서 쿠키를 저장하게 하지 않고 해당 URL이 로딩하게 되면 비지니스 로직에 맞게 해당 페이지에서 App을 호출해서 값을 넘겨서 App에서 강제로 쿠키매니저로 저장하시면 됩니다. 하지만 별로 권하고 싶지 않군요

이유는 웹에서 이미 쿠키를 저장하고 있는데(하이브리드 App 이니깐용) 구지 그걸 어플에서 다시 getCookie 해서 set을 하던지 해서 조작할 필요없다고 생각합니다. 뭐 물론 특별한 상용에서는 논외로 해야하지만용~ 아무튼 그냥 단순히 모바일 웹에서 잘 되던 쿠키가 WebView로 로딩하니깐 안된다면 위 방법을 한번 사용해 보시기 바랍니다.(거듭강조하지만 이 방법이 정확한건 아닙니다.)

그럼 참고해주시고 혹시 제가 파악한 위 사항이 잘못되었다면 저에게도 좀 알려주시기 바랍니다 ㅜ.ㅜ 그럼 잡스형에게 삿대질 할 그날까지 ~~

https://baepower.wordpress.com/2011/02/17/html5%EC%97%90%EC%84%9C%EB%8A%94/


HTML5에서는…

  1. <!DOCTYPE html>로 끝이다.
  2. <figure>,<figcaption>으로 이미지에 의미를 부여하여 멋진 앙상블을 보여준다.
  3. <small>요소는 작은 출력이라는 의미로 정말 작은 문구를 표시할때 사용되어 질 것이다.
  4. 스크립트나 링크에 더이상 type 속성을 정의하지 않아도 된다.
  5. HTML5는 XHTML이 아니라서 더이상 속성들을 감싸지 않아도 된다고는 하나 이건 이렇게 안지키는게 맞을듯…
  6. contenteditable이라는 속성 요소가 등장하여 아주 유용하게 사용될 것이다.
  7. input tag에 type을 email로 지정할 수 있게 되었다. 물론 required, autofocus속성도 추가가 되었다. 아직 브라우져별로 지원하는 정도의 차이가 크다.
  8. Placeholder 속성이 지원된다. 스크립트로 구현하던 기능인데 이 기능도 브라우져별로 지원하는 정도의 차이가 있다.
  9. Local Storage기능이 도입되어서 도메인별로 유져가 입력한 것을 브라우져가 기억하게 된다. 먼저 window.localStorage로 테스트를 해보자.
  10. 시맨틱 header와 footer라는 테그가 추가되었다. 단 컨테이너와 다를바없다. 시맨틱 웹을 위함이다.
  11. 모든 요소는 디폴트로 inline으로 표시하게 되었다. IE가 과연 이를 어떻게 지원할런지가 의문이다.
  12. hgroup테그가 등장하여 좀 더 시맨틱한 웹구현이 가능하게 되었다.
  13. <audio>테그가 등장! 다만 Webkit계열에서는 mp3를 Mozilla쪽에서는 ogg를 지원하고 있어서 또 개발자의 몫이 되었지만… IE는 아직도 지원을 안하지 아마..?!
  14. <video>테그도 등장! YouTube가 이를 정식 지원한다고 발표도 했다. 코덱쪽이 문제인데 Safari, Chrome, IE9은 H.264를 지원하기로 했는데…  Chrome은 ogg,mp4를 둘다 지원하는군… 역시 이것또한 개발자의 몫?
  15. 이 video테그에 preload라던지 controls라는 속성이 있어서 기본적인 기능제공이 강력해졌다.
  16. 정규표현식을 HTML에 직접 넣을 수 있게 되었다. 오!!
  17. header, article, section, footer 같은 컨테이너가 등장하여 div를 사용할 일이 없어지지 않았나! 물론 사용빈도는 줄어들겠지만 이것들로 모든 걸 정의 할수 없기때문에 정의할 수 없는 곳에는 div를 이용하여 정의하면 된다.
  18. client storage와 web Sockets은 원래 HTML5의 스팩에 포함되었다가 방대해지고 복잡해질 우려가 커서 별도의 프로젝트로 빠지게 되었다. 뭐 그냥 프로젝트를 별도로 진행하는 것이다.

 

그리고 들리는 말로는 HTML5가 완성이 되려면 2022년까지 기다려야 한다고 하는데 이때까지 어찌 기다린단 말인가! 적용할 수 있는 부분이 무엇인지를 미리 파악하고 할 수 있는 부분부터 적용해 나가야 할것이다.

'develop > 공통' 카테고리의 다른 글

DualStack Mobile IPv6 with Multiple Care of Address  (0) 2013.06.24
IPv4, IPv6 체크 정규식  (0) 2013.04.02
웹 표준에 대한 블로그  (0) 2012.11.26
C++ Operator Precedence  (0) 2010.02.23
유니코드 한글 음절들  (0) 2010.02.22

참고 : http://devian.tistory.com/159


PlayStore 에 등록시 보안이슈 발생 해결방안 보기


로컬 HTML(JavaScript)과 App 영역이 통신(함수호출)을 함으로써 간단한 하이브리드 앱을 만들어볼 수 있다.

1. HTML에서 App 함수 호출
   1) 멤버로 android.os.Handler 를 생성한다. 호출 시 thread 처리를 위해서 이용된다.
        private final Handler handler = new Handler();

   2) App과 Javascript간 Bridge 클래스를 생성하고, 호출될 함수를 implement 한다.
       (이 때 파리메터는 반드시 final로 선언)
       Javascript에서 호출시 별도의 Thread로 구동될 수 있도록 아래와 같이 구현한다.

          private class AndroidBridge {
            public void setMessage(final String arg) { // must be final
                handler.post(new Runnable() {
                    public void run() {
                        Log.d("HybridApp", "setMessage("+arg+")");
                        mTextView.setText(arg);
                    }
                });
            }
          }
   3) onCreate 함수에서 WebView에서 JavaScript를 Enable 하고, JavaScriptInterface로 Bridge 인스턴스를 등록한다.
        // 웹뷰에서 자바스크립트실행가능
        mWebView.getSettings().setJavaScriptEnabled(true);
        // Bridge 인스턴스 등록
        mWebView.addJavascriptInterface(new AndroidBridge(), "HybridApp");
 
    4) HTML 내에서 JavaScript에서 선언된 함수를 다음과 같이 호출 한다.
            window.<interfaceName>.<functionName>

  window.HybridApp.setMessage(msg);


2. App에서 HTML의 Javascript 함수 호출
   이부분은 간단하다....HTML에거 링크걸 때를 생각하면 되는데....
   그냥 버튼을 눌렀을 때 다음과 같이 호출하면 된다.
    mWebView.loadUrl("javascript:<함수명>('<arg>')");

    실제 구현은 다음과 같이 된다.
       mButton.setOnClickListener( new OnClickListener(){
        public void onClick(View view) {
            mWebView.loadUrl("javascript:setMessage('"+mEditText.getText()+"')");            
        }
       });

위의 방법으로 연결된 간단한 하이브리드 어플리케이션이다...




1. Android에서 Javascript함수 호출하기

 

webView.loadUrl("javascript:callJS('Hello from Android')");

 

다음과 같은 방식으로 javascript:methodname 과 같은 문자열을 넣어 WebView.loadUrl 메소드의 인자로 호출한다.



2. Javascript에서 Android 호출하기

 

/** Object exposed to JavaScript */
    private class AndroidBridge {
       public void callAndroid(final String arg) { // must be final
          handler.post(new Runnable() {
             public void run() {
                Log.d(TAG, "callAndroid(" + arg + ")");
                textView.setText(arg);
             }
          });
       }
    }

 

다음과 같이 브릿지 역활을 할 Class를 만든다.

WebView의 세팅을 바꾸고

           webView.getSettings().setJavaScriptEnabled(true);

WebView에 Javascript Interface를 추가해준다.

           webView.addJavascriptInterface(new AndroidBridge(),"android2");

HTML페이지에서 다음과 같은 방식으로 호출한다.

           window.android2.callAndroid('Hello from Browser')

android2는 addJavascriptInterface의 두번째 인자와 같다.



3. Javascript Listener 걸기

 

 webView.setWebChromeClient(new WebChromeClient() {
           @Override
           public boolean onJsAlert(final WebView view,
                 final String url, final String message,
                 JsResult result) {
              Log.d(TAG, "onJsAlert(!" + view + ", " + url + ", "
                    + message + ", " + result + ")");
              Toast.makeText(LocalBrowser.this, message, 3000).show();
              result.confirm!();
              return true; // I handled it
           }
        });

 

다음과 같이 WebView의 setWebChromeClient를 이용한다.

위 예제는 Javascript의 alert메소드 발생시 이벤트이다.



=============================================================================================================


'develop > android' 카테고리의 다른 글

Recents App List에서 실행됐는지 체크  (0) 2013.12.10
Windows에서 git로 안드로이드 소스 받기  (0) 2013.07.29
Webview cookie 설정  (2) 2012.11.26
공유하기 메뉴  (0) 2012.08.03
URL 받기  (0) 2012.08.03

=== 1일 이내에 수정된 파일

find ./* -mtime -1 (현재 폴더 미포함)
find . -mtime -1 (현재 폴더 포함)


=== 1일 이내에 접근된 파일

find ./* -atime -1


=== 1일 이내에 상태가 변경된 파일

find ./* -ctime -1



=== man 페이지 내용 ===

-atime n

              File  was  last  accessed n*24 hours ago.  When find figures out how many 24-hour periods ago

              the file was last accessed, any fractional part is ignored, so to match -atime +1, a file has

              to have been accessed at least two days ago.


-ctime n

              File's status was last changed n*24 hours ago.  See the comments for -atime to understand how

              rounding affects the interpretation of file status change times.


-mtime n

              File's  data was last modified n*24 hours ago.  See the comments for -atime to understand how

              rounding affects the interpretation of file modification times.

'일상' 카테고리의 다른 글

직장내 잘못 된 압존법(존칭)  (0) 2020.01.27
아이폰 6s 로즈골드 64G 구매  (0) 2015.10.23
웃음따위...  (0) 2010.04.14

참조
    1. http://sidharthdeshpande.blogspot.kr/2011/08/postgresql-904-streaming-replication.html
    2. http://wiki.postgresql.org/wiki/Streaming_Replication


2번 참조가 공식 사이트의 사용방법이고, 1번 참조가 좀 더 자세하게 나온 것이다.


PostgreSQL은 9.1버전의 deb파일을 구해서 ubuntu 10.0.4에 설치하여 테스트했다.
    - PostgreSQL 9.1 설치 : http://wiki.openscg.com/index.php/Postgres_9.1_DEB
    - PostgreSQL 9.1 deb 및 rpm 파일 : http://www.openscg.com/se/postgresql/packages.jsp


설정은 master를 먼저 하고, slave를 실행한다.
ubuntu 기준으로 설치 시 /opt/postgresql/9.1/ 폴더에 설치가 되었다.
설정 중 경로가 없는것들이 몇 개 있는데 mkdir로 만들어 준다.


=== Master 설치 ===

1. PostgreSQL 9.1 설치 및 초기화
    # dpkg -i postgresql...deb
    # /etc/init.d/postgres-9.1-openscg start

2. 환경설정파일 수정
    # cd /opt/postgres/9.1/data
    - postgresql.conf파일과 pg_hba.conf파일을 수정해야 하는데, 수정하는 내용은 위의 참조 사이트를 참고한다.

3. DB 및 테이블 생성
    - 실제 데이터가 들어갈 DB 및 테이블을 생성
    - DB 생성은 createdb 를 사용하면 된다.

4. DB 데이터 백업
    - 2번 참조 사이트의 How to Use섹션 5번, 6번 항목을 참고한다.
    - rsync는 scp를 내부적으로 사용한다. 따라서 파라미터도 scp에 들어가는 것과 같다.

5. 4번까지 끝나면 slave의 /srv/pgsql/standby 폴더에 /opt/postgres/9.1/data의 파일들이 전부 복사되어 있다.


=== Slave 설치 ===

6. PostgreSQL 9.1 설치
    # dpkg -i postgresql....db
    - slave에서는 초기화를 하지 않는다.

7. DB 데이터 파일 복사
    - 4번에서 복사한 /srv/pgsql/standby의 모든 파일을 /opt/postgres/9.1/data 폴더에 복사한다.
    - 그 후 권한과 사용자를 변경한다.
    # cd /opt/postgres/9.1/data
    # chmod 700 .
    # chown -R postgres:postgres .

8. 환경 설정파일 수정
    - data폴더의 모든 파일을 복사 하였기 때문에 master와 똑같은 설정이 몇가지 있어서 수정한다.
    - postgresql.conf 파일의 master설정 부분을 주석처리한다.
    # vi postgresql.conf
    max_wal_senders = 5 -> #max_wal_senders = 5
    
wal_keep_segments = 32 -> #wal_keep_segments = 32
    - slave라는것을 알 수 있도록 hot_standby 항목의 값을 변경한다
    #hot_standby = off -> hot_standby = on

    # vi pg_hba.conf
    - replication으로 설정된 항목 삭제

9. 환경설정 파일 추가
    - 2번 참조 사이트의 How to Use섹션 9번을 참고한다.

10. 마무리
    - 1번 참조 사이트에서 slave의 recovery.conf파일을 생성 한 후 하는 명령어를 실행한다.
        - initdb 실행
        - DB 시작

    - 정상적으로 replication이 설정되었다면 1번 참조 사이트의 로그 내용이 출력된다. 로그는 pg_log 폴더에 있다.

11. 테스트
    - master에서 DB에 아무 값이나 넣어본 후 slave에서 정상적으로 데이터가 복제되나 확인해본다.


※ 에러 사항

1. slave를 시작하는데 시작하는 시간이 오래 걸리고, 로그 내용중 "database system identifier differs between the primary and standby" 이란 에러가 있다면, slave에서 DB초기화를 해서 생긴 에러다.
    ==> data폴더를 삭제 후 다시 slave 설정을 하거나, 그래도 안되면 slave에서 PostgreSQL 9.1을 삭제한 후 다시 설치한다.

2. FATAL:  data directory "/opt/postgres/9.1/data" has group or world access
DETAIL:  Permissions should be u=rwx (0700).
    ==> 말 그대로 data폴더의 권한을 700 으로 주란 소리다.



참조 : http://slony.info/documentation/1.2/firstdb.html

replication의 초기화는 master에서 설정하고, replication 동작은 slave에서 실행한다. 참조의 쉘 스크립트 자체가 master->slave로 되어 있다.


master에서 초기화 쉘 스크립트를 만든다. 파일명은 맘대로....
참조 웹 페이지의 2.3.1 섹션의 쉘 스크립트를 가져다가 적당히 수정한다. 테이블이라던가.... 패스워드라던가...
참조에는 없는 부분인데... store path 아래에 아래 두줄을 넣어준다.

store listen (origin=1, provider = 1, receiver =2);
store listen (origin=2, provider = 2, receiver =1);


만든 쉘 스크립트를 실행 한 후 참조에 있는대로 master와 slave에서 slon데몬을 실행한다.

slon $CLUSTERNAME "dbname=$MASTERDBNAME user=$REPLICATIONUSER host=$MASTERHOST" -> master

slon $CLUSTERNAME "dbname=$SLAVEDBNAME user=$REPLICATIONUSER host=$SLAVEHOST" -> slave

정상적으로 설정이 되었다면 master(node에서 id를 1로 지정)의 로그 중 slave(node에서 id를 2로 지정)와의 싱크중이라는 뜻으로 대략 아래와 같은 메세지가 출력된다. slave의 로그는 id에 해당하는 부분만 1로 출력된다.

remoteListenThread_2: LISTEN
remoteWorkerThread_2: Received event 2,nnn SYNC


만약 db_getLocalNodeId() returned 2 - wrong database? 이런 에러가 뜨면 ip문제일 수도 있다. (테스트 시 localhost로 지정했더니 이같은 에러가 나타나 localhost의 실제 ip주소를 적어주었다. (1) 초기 설정 편의 예시를 보면 된다)

이 에러가 떴다면 master와 slave에서 일단 이전에 만든 정보를 삭제해준다.
psql -h localhost -U postgres -d test_db -c "drop schema _$CLUSTERNAME cascade"

그 후에 다시 초기화 스크립트를 실행해준다.


싱크가 잘 된다면, slave에서 데이터를 받아오도록 하는 스크립트를 실행한다. 역시나 마찬가지로 참조의 스크립트를 가져다가 적당히 수정해서 사용하면 된다.

데이터 가져오는 스크립트를 한번 실행하면 그 후로는 pc가 껐다 켜져도 데몬만 실행하면 된다.


테스트를 해본다. 잘 된다. 끗! 

참고 : http://slony.info/documentation/1.2/firstdb.html

Ubuntu 10.0.4에서 설치하였기 때문에 PostgreSQL 9.0 미만의 버전에서 사용하는 방법이다.
PostgreSQL 9.0 이상은 Streaming Replication이라는 방법을 지원한다.(http://wiki.postgresql.org/wiki/Streaming_Replication)


계정은 기본 계정인 postgres를 그냥 사용했다.
어차피 계정을 새로 만들어도 slave에서 password 설정을 해줘야 한다. (master에서 연결하기 위해서)

계정의 password 설정하는것을 제외한 모든 작업은 master에서 진행한다.


postgres 계정의 비번 변경 방법.

# sudo su - postgres
# psql template1
# alter user postgres with password '1234';


- Replication에 필요한 프로그램 목록
    - postgresql-8.4
    - postgresql-8.4-slony1
    - slony1-bin


- .bashrc 설정(master, slave 전부 설정)

CLUSTERNAME=slony_example
MASTERDBNAME=test_db
SLAVEDBNAME=test_db
MASTERHOST=192.168.0.71
SLAVEHOST=192.168.0.72
REPLICATIONUSER=postgres

- 재부팅 하지 않고 계속 작업할 경우 export로 환경변수 셋팅을 해준다.
- 만약 서로 다른 PC에서 작업할 경우 host의 ip주소 중 localhost가 입력되면 안된다.


밑의 작업은 master에서 postgres 계정으로 전환한 후 작업한다.


- DB 생성

      # createdb -O $REPLICATIONUSER -h $MASTERHOST $MASTERDBNAME
      # createdb -O $REPLICATIONUSER -h $SLAVEHOST $SLAVEDBNAME


- Password 설정 (master, slave 전부 설정한다)


- table 생성
      # psql -U $REPLICATIONUSER -h $MASTERHOST -c "create table history();"
      # psql -U $REPLICATIONUSER -h $MASTERHOST -d $MASTERDBNAME -c "begin; alter table
      history add column id serial; update history set id =
      nextval('history_id_seq'); alter table history add primary key(id); commit"


- pl/pgSQL
    # createlang -h $MASTERHOST plpgsql $MASTERDBNAME


- schema 복제
    # pg_dump -s -U $REPLICATIONUSER -h $MASTERHOST $MASTERDBNAME | psql -U $REPLICATIONUSER -h $SLAVEHOST $SLAVEDBNAME

+ Recent posts