2018년 10월 29일 월요일

181029 컴퓨터 정리




   요약


   일일 파일
180607.txt
http://programmingsummaries.tistory.com/302
우분투, 안드로이드 스튜디오 설치, jdk 삭제

http://blog.naver.com/PostView.nhn?blogId=elepartsblog&logNo=220823075016&parentCategoryNo=&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView
라즈베리파이 rc카
https://m.blog.naver.com/PostView.nhn?blogId=chandong83&logNo=221084688966&proxyReferer=https%3A%2F%2Fwww.google.com%2F
https://m.blog.naver.com/PostView.nhn?blogId=chandong83&logNo=221084688966&proxyReferer=https%3A%2F%2Fwww.google.com%2F
180610.txt
http://webnautes.tistory.com/995


# -*- coding: utf-8 -*-

# 라즈베리파이 GPIO 패키지
import RPi.GPIO as GPIO
import spidev
from time import sleep
import pygame
import sys
from pygame.locals import *

# 모터 상태
STOP  = 0
FORWARD  = 1
BACKWORD = 2

# 모터 채널
CH1 = 0
CH2 = 1

# PIN 입출력 설정
OUTPUT = 1
INPUT = 0

# PIN 설정
HIGH = 1
LOW = 0

# 실제 핀 정의
#PWM PIN
ENA = 26  #37 pin
ENB = 0   #27 pin

#GPIO PIN
IN1 = 19  #37 pin
IN2 = 13  #35 pin
IN3 = 6   #31 pin
IN4 = 5   #29 pin
IN5 = 17


# 핀 설정 함수
def setPinConfig(EN, INA, INB):       
    GPIO.setup(EN, GPIO.OUT)
    GPIO.setup(INA, GPIO.OUT)
    GPIO.setup(INB, GPIO.OUT)
    # 100khz 로 PWM 동작 시킴
    pwm = GPIO.PWM(EN, 91000)
    # 우선 PWM 멈춤.  
    pwm.start(0)
    return pwm

# 모터 제어 함수
def setMotorContorl(pwm, INA, INB, speed, stat):

    #모터 속도 제어 PWM
    pwm.ChangeDutyCycle(speed) 

    #앞으로 A=1, B=0
    if stat == FORWARD:
        GPIO.output(INA, HIGH)
        GPIO.output(INB, LOW)

    #뒤로 A=0, B=1
    elif stat == BACKWORD:
        GPIO.output(INA, LOW)
        GPIO.output(INB, HIGH)

    #정지 A=0, B=0
    elif stat == STOP:
        GPIO.output(INA, LOW)
        GPIO.output(INB, LOW)


# 모터 제어함수 간단하게 사용하기 위해 한번더 래핑(감쌈)
def setMotor(ch, speed, stat):
    if ch == CH1:
        #pwmA는 핀 설정 후 pwm 핸들을 리턴 받은 값이다.
        #37, 35 핀의 값
        setMotorContorl(pwmA, IN1, IN2, speed, stat)
    else:
        #pwmB는 핀 설정 후 pwm 핸들을 리턴 받은 값이다.
        setMotorContorl(pwmB, IN3, IN4, speed, stat)


# 라즈베리와 아두이노 연결 모듈 만들기
# GPIO 모드 설정
GPIO.setmode(GPIO.BCM)

spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz=1000000

#라즈베리파이에서 아날로그 신호를 읽기 위한 함수
#ADC를 통해 변환된 아날로그 신호를 라즈베리파이에서 SPI 통신 프로토콜을 이용하여 읽기 위해서는 라즈베리파이에서 SPI를 사용할 수 있게 해줘야 한다.
def analog_read(channel):
        #안에 있는 데이터를 쓰고 리턴된 값을 반환한다.
    r = spi.xfer2([1,(8 + channel) <<  4, 0])
        #8비트 중 1, 2번째 비트는 ADC 데이터의 9, 10번째 비트, 세번째는 하위 8비트를 의미한다.
    adc_out = ((r[1]&3) << 8) + r[2]
    return adc_out


#모터 핀 설정
#핀 설정후 PWM 핸들 얻어옴
pwmA = setPinConfig(ENA, IN1, IN2)
pwmB = setPinConfig(ENB, IN3, IN4)

GPIO.setup(IN5, GPIO.IN)
#제어 시작

pygame.init()
screen = pygame.display.set_mode((640, 480))

pygame.display.set_caption('RaspiRobot')
pygame.mouse.set_visible(0)

dist = 0
state_on=0


def go(keys):
    if keys[pygame.K_UP]:
        setMotor(CH1, 100, FORWARD)
    if keys[pygame.K_DOWN]:
        setMotor(CH1, 100, BACKWORD)
    if keys[pygame.K_LEFT]:
        setMotor(CH2, 100, FORWARD)
    if keys[pygame.K_RIGHT]:
        setMotor(CH2, 100, BACKWORD)

def stop():
    setMotor(CH1, 80, STOP)
    setMotor(CH2, 80, STOP)


while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            GPIO.cleanup()
        sys.exit()
    if event.type == KEYUP:
                stop()
        reading = analog_read(0)
                #전압 값 계산, 몇 V인지
        voltage = reading * 3.3 / 1024
        #print("R = %d \t V = %f" %(reading, voltage))

    dist = analog_read(0)
    print(dist)
    print("\n")
    #핀의 값을 받아서 state_on 상태에 입력
    state_on = GPIO.input()

    keys = pygame.key.get_pressed()
    if state_on:
        stop()
    else:
        go()
   
180618.txt
https://m.blog.naver.com/PostView.nhn?blogId=speedprinse&logNo=220205590326&proxyReferer=https%3A%2F%2Fwww.google.com%2F

http://blog.naver.com/PostView.nhn?blogId=ziefer&logNo=220651475398&parentCategoryNo=6&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView

https://m.blog.naver.com/PostView.nhn?blogId=speedprinse&logNo=220204494919&proxyReferer=https%3A%2F%2Fwww.google.com%2F#

https://www.google.com/search?client=ubuntu&hs=Jh0&channel=fs&ei=1LMmW6q9LNKK8gWW6Z2gBQ&q=rc%EC%B9%B4+%EC%9E%90%EB%8F%99%EC%A3%BC%EC%B0%A8%2C+python&oq=rc%EC%B9%B4+%EC%9E%90%EB%8F%99%EC%A3%BC%EC%B0%A8%2C+python&gs_l=psy-ab.3...6969.9968.0.10117.9.8.1.0.0.0.190.780.0j6.6.0....0...1c..64.psy-ab..2.0.0....0.DPqSTmqlMmo


   딥러닝 파일
NYN 으로 시작하는 자연어처리와 딥러닝.txt
//http://sacko.tistory.com/54

NTN은 Neural Tensor Network의 약자로 스탠포드 대학교 교수인 Richard Socher(2013)가 "Reasoning With Neural Tensor Networks for Knowledge Base Completion"에서 지식을 넘어선 추존(Reasoning Oser Knowledge)을 위해 제시한 딥러닝 모델이다.

1. NTN은 자연어처리와 딥러닝의 교집합니다.
이 모델에서 다루는 주요 주제는 Question Answering과 Information Retrieval이다. 이는 NLP의 영역으로 컴퓨터가 인간의 언어를 이해하는 것에서 시작하여 문서 분류나 기계번역, 질의응답 등으로 확장된다. 또한, word2vec이나 skip-gram 알고리즘, Negative Sampling 학습 방법 등을 사용하는데 이는 자연어 처리 부분이다.
그리고 NTN모델은 일반적인 인공 신경망 모형으로 순전파와 역전파를 모두 사용한다. 딥러닝은 인간의 인식을 모방하는 영역에서 많은 성능 사으이 우위를 보여왔다. 그리고 수많은 input feature가 있을 때에 가장 적합한 방법이기도 하다. 따라서 자연어처리 분야에서도 많이 활용되어 왔다.
Natural Language Processing와 Deep Learning의 큰 두 가지 축으로 이루어진 모델이다. 따라서 데이터를 구성하고 모델을 학습하는 technique에 있어서 자연어처리에서 사용하는 기존의 이론적인 배경과 기법들을 알아야하며 딥러닝의 상위 범주인 머신러닝의 학습 기법에 대한 이해가 필요하다.
SyntaxNet.txt
//https://cpuu.postype.com/post/166917

SyntaxNet은 인공신경망 프레임워크이다. 핵심기능이라 할 수 있는 자연어 이해(Natual Language Understanding)기능을 Google TensorFlow를 사용하여 구현하였다. (영어에 한정하여)텍스트 분석이 가능한 구문 분석기를 제공한다. 일명 Parsey McParseface라고 부르며, 이미 학습이 완성된 상태로 제공되기 때문에 별도의 trainning없이, 그저 활용하면 된다.
Parsey McParseface는 언어의 구조를 분석하도록 학습된 아주 강력한 머신러닝 알고리즘이다. 뿐만 아니라, 주어진 문장에서 각 개별 구성단어의 기능적 역할을 파악하고 구분할 수 있다. 이것을 사용하여 다양한 개발자분들과 연구자분들이 각각 관심있으신 분야(자동 정보 추출, 언어 번역, 자연어 이해 등)에서 유용하게 사용하실 수 있으리라 기대한다.

SyntaxNet은 어떤 원리로 작동하는가?
학계에서 통상 구분 분석기(Syntacic parser)라고 부르는 것의 Framework이다. 대부분의 NLU 시스템에서 핵심적인 요소라고 보면 된다. 입력값으로 문장이 주어지면, 각각을 어절 단위로 구분하여 각 단어의 문법적인 역할을 파악하고 해당 tag를 부여한다. 그리고 의존성 구분분석 트리로 표현한다. 이렇게 함으로써 주어진 문장을 구성하고 잇는 각 단어들의 문법적인 관계를 결정할 수 있다.

컴퓨터가 문장을 정확하게 분석하는 것이 왜 어려운가?
컴퓨터 구문분석에 있어서 가장 큰 문제로 꼽을 수 있는 것은, 인간의 언어가 상당히 복잡한 수준의 모호함을 갖기 때문이다. 신기하게도 인간은 언어를 사용할 때 아주 놀라울정도로 모호성 문제에 잘 대처한다. 하지만 컴퓨터가 처리하기에는 쉽지 않다. 아주 긴 문장에 대해, 가능한 다양한 중의적 해석을 모두 검토하려면 그 조합의 경우의 수가 급격히 커진다. 보통 그중 상당수는 상식적으로 말이 안되는 해석일 수도 있겠지만, 그럼에도 불구하고 그것이 문법적으로 가능한 해석이라면 반드시 Parser의 검토를 거쳐서 후보군에서 기각시킬지 판단해야 한다.

SyntaxNet은 위에서 언급한 모호성문제에 대해 인공신경망을 적용하여 해결한다. 입력된 문장을 왼쪽에서부터 오른쪽으로 처리하면서, 각 단어들 사이의 의존성을 고려하여 점진적으로 추가된다. 각 단계마다 모호한 가능성들에 대해 명확한 판단을 내려야하는데, 이때 Neural network을 사용하여 좀 더 그럴듯한 방향으로 해석하도록 결정합니다. 이런 이유에서 이 모델에서는 beam search라는 방식을 사용합니다. 매번 선택의 순간마다 최적우선탐색을 하도록 단순반복하는 것보다는, 다양한 가능성을 유지시키다가(Only K most promising states are kept for future consideration), 명백한 결격사유가 등장했을 때에야 비로소 후보군에서 탈락시키고 최적의 모범답안을 채택하는 것이다.

논문에서 자세히 설명했듯이, 예측 정확성을 최대치로 끌어올리기 위해서는 양질의 데이터를 통해 뉴럴넷을 잘 학습시키고, 그 결과물들을 잘 다듬에서 통합시키는 것이 매우 중요하다.
Parsey McParseface와 SyntaxNet은 저희가 구글의 TensorFlow 프레임워크를 사용하여 미지 학습시켜둔 아주아주 정교한 뉴럴네트워크이다. 여러분은 이미 학습된 뉴럴넷을 그저 가져다가 사용하셔도 되고, 또는 구글에서 제공하는 Universal Treebanks Project에서 데이터를 통해, 당신만의 새로운 구문분석 모델을 당신의 컴퓨터에서 직접 학습시킬 수도 있다.

 https://github.com/tensorflow/models/tree/master/research/syntaxnet
딥러닝으로 NLP 하자.txt
//http://sacko.tistory.com/2

자연어처리(NLP)
Natural Language Processing은 다음의 영역의 교집합이라고 할 수 있다.
컴퓨터 과학, 인공지능, 언어학

자연 언어를 컴퓨터가 처리하고 이해할 수 있도록 하는 것이다. 예를 들면, 업무 수행, 예약하기, 물건 구매, 질문잡변 등이 위에서 말한 유용한 업무수행이다.
speech 또는 text로부터 형태소를 분석해 syntactic analysis(의미적 분석)을 하고 그 의미를 해석할 수 있도록 하는 것이 전체적인 NLP 방향이라고 할 수 있다.

Natural Language
인간의 언어는 일종의 신호 시스템이다.(discrete/symbolic/categorical) 다시 말해 언어는 사람이 자신이 말하고자 하는 바를 상세하게 전달하기 위한 신호체계 같은 것이다.
인간의 언어가 상징적/분류적 신호체계라고 하지만, 인간의 뇌에서 신호화는 activation의 연속적인 패턴으로 보인다. 그리고 상징은 소리 혹은 시각적으로 연속된 신호 형태로 변환된다. 너무나 많은 단어, 단어의 상징적 신호화는 기계학습에서 sparsity 문제를 야기한다.

딥러닝
기계학습의 하위분야이다. 대부분의 기계학습 방법은 human-designed representations와 input fearures 덕분에 잘 작동한다. 기계학습은 최종 예측을 하기 위해 최적화된 가중치를 만들어내는 수주닝 되었다.
*features는 같은 의미를 분야마다 다르게 표현한다. 우리가 아는 independent variable, explanatory vaiable, input variable, predictor variable이 같은 의미로 사용된다.

Word의 의미
단어의 의미를 어떻게 대신 표현할 수 있을까?
언어학적 개념이 바탕이 되어 컴퓨터 상에서 단어가 의미를 갖게하기 위해 일반적으로 분류체계를 활용한다. 아래 샘플 코드를 통해서 확인할 수 있다.
...
symbolic 방식&statistical NLP의 문제점
위와 같은 방식으로 단어를 개별적으로 그리고 사전에 대신하여 표현하는 방식은 많은 문제가 있다. 이를 rule-based 그리고 통계적 NLP방법이라고 일컬으며 단어를 대상으로 표현하는 단일한 상징으로 보는 것이다. vector 공간에서 이를 설명하면, 이는 하나의 1과 수많은 0으로 구성된 단일 벡터를 의미한다. 차원의 개수는 기하급수적으로 늘어난다.
우리는 이를 one-hot representation이라고 부르며 지엽적인 표현 방식이라고 본다. 이는 general 하게 적용되기 어려운 방식임을 뜻한다.
이를 극복하기 위해 distrivutional similarity based representation의 개념이 소개되었으며, 이는 해당 단어의 주변 단어들을 통해 그 단어가 의미하는 바가 무엇인지 찾는 것이다. 이는 비슷한 distribution를 가진 단어들은 비슷한 meaning를 갖을 것이라는 가정에서 출발한다. 단어들이 같은 문단 혹은 문장에서 계속 발견된다면 비슷한 분포를 보일 것이고 유사한 의미를 가질 것이라 생각할 수 있으며, 많은 글을 학습하면서 이러한 관계를 보다보면 이후에는 예측이 가능할 것이다.

word2vec개요
간단하게 말하면 모든 단어를 vector로 표현하여 단어 사이의 유사성과 차이점을 계산한다. 계산된 결과를 바탕으로 그 주변단어와의 관계를 통해 단어가 표현하는 바를 직접적으로 예측하는 것이다.
Algorithms: Skip=gram(SG), Continuous Bag of Words(COBW)
Training Methods: Hierarchical softmax, Negative sampling

word vetors 기초
영어 같은 경우 1,300만 개의 tokens들이 있는데 모든 token들이 독립적일 수 있는지 서로 관계가 없다고 할 수 있을지 모르겠다. N차원의 공간에서 각 단어는 실제로 존재할 것이고, 각 차원 안에서 각 단어는 의미를 갖을 것이다. 그 다음, 우리는 각 단어를 one-hot vector로 표현해 볼 수 있다. vector의 크기는 우리가 가진 어휘 수만큼 많을 것이다. 그리고 one-hot vector방식으로 표현된 각 단어는 완전히 독립된 개체로 표현될 것이다. 앞에서 말한 것처럼 one-hot vector 방식으로는 단어 간의 유사성을 찾을 수 없다. 따라서, 1)단어의 벡터 공간 크기를 줄일 필요가 있고, 2) 각 단어의 관계를 발견할 수 있는 방향으로 단어를 공간에서 표현하는 방법이 필요하다.

SVD Based Methods
Singular Value Decomposition에 기반한 방법, 전제 데이터를 한 바퀴 탐색하고 동시 발생한 단어의 빈도를 계산하여 matrix 형태로 표현하고 Singular Value Decomposition을 활용해서 USVT값을 얻는 것이다.
Skip-gram
1부터 T까지 각 단어의 m반경만큼 떨어진 주변단어를 예측하는 것
문과생도 이해하는 딥러닝.txt
//http://sacko.tistory.com/10?category=632408

   언어 공부 파일
javaStudy.txt
https://nesoy.github.io/articles/2018-04/Java-Serialize
<Java의 직렬화(Serialize)란>

직렬화
-자바 시스템 내부에서 사용되는 Object 또는 Data를 외부의 자바 시스템에서도 사용할 수 있도록 byte형태로 데이터를 변환하는 기술
-JVM의 메모리에 상주(힙 또는 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술

역직렬화
-byte로 변환된 Data를 원래대로 Object나 Data로 변환하는 기술을 역직렬화하고 부릅니다.
-직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태.

*직렬화 시작하기
직렬화 조건
-java.io.Serializable인터페이스를 상속받은 객체는 직렬화 할 수 있는 기본 조건입니다.
-public class Memeber implements Serializable

직렬화 방법
-java.io.ObjectOutputStream를 사용하여 직렬화를 진행합니다.

*역직렬화 시작하기
역직렬화 조건
-직렬화 대상이 된 객체의 클래스가 클래스 패스에 존재해야 하며 import 되어 있어야 한다.
-중요한 점은 직렬화와 역직렬화를 진행하는 시스템이 서로 다를 수 있다는 것을 반드시 고려해야 한다.
-자바 직렬화 대상 객체는 동일한 serialVersionUID를 가지고 있어야 한다.
 -private static final serialVersionUID = 1L;
-serialVersionUID이 왜 필요한지 자세한 내용은 아래에 추가했습니다:)

역직렬화 방법
-java.io.ObjectInputStream를 사용하여 역직렬화를 진행합니다.


직렬화방법에는 여러 Format이 존재합니다.
-표형태의 다량의 데이터를 직렬화할때는 CSV형태
-구조적인 데이터는 XML, JSON형태.

CVS
-데이터를 표현하는 가장 많이 사용되는 방법 중 하나로 콤마 기준으로 데이터를 구분하는 방법입니다.

JSON
-

자바의 직렬화 왜 사용하는가?
-복잡한 데이터 구조의 클래스의 객체라도 직렬화 기본 조건만 지키면 큰 작업 없이 바로 직렬화, 역직렬화가 가능합니다.
-데이터 타입이 자동으로 맞춰지기 때문에 관련 부분을 큰 신경을 쓰지 않아도 됩니다.

어디에 사용되는가?
*서블릿 세션(Servlet Session)
-세션을 서블릿 메모리 위에서 운용한다면 직렬화를 필요로 하지 않지만, 파일로 저장하거나 세션 클러스터링, DB를 저장하는 옵션 등을 선택하게 되면 세션 자체가 직렬화가 되어 저장되어 전달됩니다.

*캐쉬
-Ecache, Redis, Memcached 라이브러리 시스템을 많이 사용됩니다.

*자바 RMI(Remote Method Invocation)
-원격 시스템 간의 메시지 교환을 위해서 사용하는 자바에서 지원하는 기술.



<Java transient이란?>

Java transient이란?
-transient는 Serialize하는 과정에 제외하고 싶은 경우 선언하는 키워드입니다.

왜 필요할까요?
-패스워드와 같이 보안정보가 직렬화되는 과정에서 제외하고 싶은 경우에 적용합니다.
-다양한 이유로 데이터를 전송하고 싶지 않을 때 선언할 수 있습니다.

이름에 transient keyword를 추가하면 어떨까요?
-private transient String name;
-겨로가를 확인해보니 field는 유지되지만 null값이 대입되는 것을 확인할 수 있었습니다.

주의해야 할 점은 없을까요?
-적용하는 Data에 대해 이해가 필요합니다.
-실제로 필요가 없는지에 대한 고려.
-Data를 제외하였을 경우에 서비스 장애에 이상이 없는지에 대한 고려.


http://april-21.tistory.com/11
<Synchronized에 대하여>
비동기적으로 여러 쓰레드가 실행되고 있을 때 어떤 특정 작업들은 꼭 동기화 되어야만 하는 부분이 있을 수 있다. 예를 들어 100만원인 적금되어 있는 하나의 은행 계좌에서 A, B 두 사람이 동시에 100만원씩 빼려 할 때, A가 100만원을 빼고 잔액을 0원으로 줄이고 있는 중에 B가 100만원을 빼가버릴 수도 있다. B가 100만원을 빼내는 시점에는 아직 잔액계산이 안돼 여전히 잔액이 100만원일 수 있기 때문이다. 이런 경우에는 필히 동기화를 하여 A의 출금 과정이 끝나기 전에는 다른 사람은 해당 계좌에 접근할 수 없도록 해야 한다.

자바에서 이러한 동기화를 Synchronized라는 것으로 지원한다.
Synchronized에는 2가지 방식이 있는데, Synchronized method와 Synchronized block이다.

Synchronized method
A클래스의 printA2 메소드와 같이 메소드 선언부에 synchronized 를 붙여 선언할 수 있다.
synchronized method는 lock을 객체로 하여 한 쓰레드가 printA2() 메소드를 실행하는 동안에는 다른 스레드가 printA2()를 호출할 수 없다.
주의사항:
1. lock을 객체로 한다고 했기 때문에, 만일 다른 객체라면 상관없이 실행 가능하다.
2. synchronized method도 아니고, synchronized block도 가지지 않은 메소드가 있다면, 한 스레드가 synchronized된 메소드를 실행 중에 그렇지 않은 메소드는 동시에 실행 가능하다.

Synchronized block
메소드 내부 모든 코드를 synchronized로 블럭처리하면 synchronized method와 동일한 기능이 된다. synchronized(lock){}블록으로 감싸서 선언가능하다.
해당 블록 안의 코드는 동기화되어 인자로 들어간 lock을 갖고 있지 않은 쓰레드는 동시에 실행 불가능하다.

일반적으로 synchronized block을 사용할 때는 관습상 synchronized(this){...}와 같이 lock을 this로 하는 경우가 많다. 즉 해당 객체를 lock으로 한다는 얘기다. 만일 this를 lock으로 하고 싶지 않다면, 다른 Object를 lock으로 해도 상관없다. 동일한 lock으로는 동시에 실행 불가능하고, lock을 다른 것으로 한다면 동시 실행 가능하다.

주의할 점은 synchronized는 꼭 필요한 경우에만 사용해야 한다는 것이다. synchronized는 한 쓰레드가 해당 메소드를 실행하는 동안, 다른 쓰레드는 하염없이 기다려야 하기 때문에 전반적으로 프로그램의 속도를 느리게 만든다. 그러나 꼭 필요한 경우가 아니라면 사용을 지양하도록 하는 게 좋다.

https://m.blog.naver.com/PostView.nhn?blogId=baek2187&logNo=150139144611&proxyReferer=https%3A%2F%2Fwww.google.com%2F
<SWIG>
Simplifed Wrapper and Interface Generator, C나 C++로 작성된 컴퓨터 프로그램이나 라이브러리들을 루아, 펄, php, 파이썬, R, 루비, Tcl과 같은 스크립트 언어 및 C#, 자바, 자바스크립트, Go, 모듈러-3, Ocamle, 옥타브 등의 다른 언어들과 연결하는데 사용하는 오픈소스 소프트웨어 도구이다.

http://oniondev.egloos.com/558949
<BlockingQueue>
Queue가 꽉찼을 때 삽입 시도/ 비어있을 때의 추출 시도를 막는다는 것이다.
자동으로 막는 기능이 있어 blockingQueue의 구현체는 모두 Thread-safe하다.

ArrayBlockingQueue
-고정배열에 일반적인 Queue를 구현한 클래스, 생성 후 크기변경 불가
-꽉찼을 때 추가 block, 비었을 때 추출 block
-선택적으로 공평성 정책을 두어 block한 thread들의 순차적 대기열 생성
(대기열 처리에 대한 정확한 순서 보장 X, 공평성 따짐-throughput 감소되나 variablity를 줄이고 starvation을 해소한다.)

BlockQueue의 Proguctor-Consumer구조 기본 용법


http://cris.joongbu.ac.kr/course/java/api/javax/sound/sampled/class-use/TargetDataLine.html
<javax.sound.sampled.TargetDataLine 사용>
javax.sound.sampled 샘플화된 오디오 데이터의 수중에 넣어 처리 및 재원시 인터페이스 및 클래스를 제공.


http://javacan.tistory.com/tag/PipedInputStream
<Java I/O - pipedInputStram과 pipedOutputStream>
도스나 유닉스의 명령어를 생각하면 쉽다.
예를 들어 도스에서 'type 파일명| sort'이런 것과 같다.(파일명을 찾고 정렬)

PipedInputStream: 파이프로 연결된 입력 스트림은 파이프로 연결된 출력 스트림에 연결되어야 합니다. 파이프된 입력스트림은 파이프된 출력 스트림에 기록되는 데이터 바이트를 제공합니다.
통상 데이터는 1개의 thread 에 의해 PipedInputStream객체로부터 읽히고, 데이터는 다른 Thread에 의해 대응하는 PipedOutputStream에 기입해집니다. 스레드를 교착상태로 만들 수 있으므로 단일 스레드에서 두 개체를 모두 사용하려고 시도하지 않는 것이 좋습니다.
new PipedInputStream(PipedOutputStream), 파이프로 연결된 출력 Stream src에 접속합니다.

PipedOutputStream: 파이프된 출력 스트림을 파이프된 입력 스트림에 연결하여 통신 파이프를 만들 수 있습니다.

리눅스나 기타 시스템에서 프로세스 사이에 데이터를 주고받을 때 사용되는 방법 중의 하나가 파이프를 이용하는 것이다. 파이프를 이용하여 다른 프로세스에 데이터를 전달하거나 전달받을 수도 있고, 또한 파이프를 통해서 한 프로세스가 다른 프로세스를 제어할 수도 잇다. 이와 비슷하게 자바도 파이프 스트림을 사용하여 스레드 사이에 데이터를 주고받거나 스레드의 프름을 제어할 수 있다.
두 스트림이 서로 연결되어 있다는 것은 PipiedOutputStream을 통해서 출력한 데이터를 PipedInputStream을 통해서 읽어온다는 것을 의미한다. 즉, PipedInputStream의 read메소드는 PipedOutputStream의 write 메소드를 사용하여 출력한 데이터를 읽어오게 되며, 만약 PipedOutputStream이 데이터를 출력하지 않는다면 PipedInputStream의 read메소드는 읽어올 수 있는 데이터가 없으므로 블럭킹된다.

*멀티 스테드와 파이프 스트림
파이프 스트림은 여러 개의 스레드가 서로 데이터를 주고받아야 하는 경우에 유용하게 사용될 수 있다. 예를 들어 공장의 컨테이너 벨트 시스템을 시뮬레이션하는 프로그램을 개발해야 하는데, 이 컨베이어 벨트 시스템은 '가열-제조-포장'의 라인이 유기적으로 동작하는 시스템이라고 가정해보자. 이때, '가열' 라인을 통해서 처리된 원료는 '제조'라인으로 전달되고, '제조'라인을 통해서 생성된 제품은 '포장'라인에 전달되어 포장처리 된다고 하자.
이 세 라인은 유기적으로 연결되어 있지만 서로 독립적으로 동작한다. 단지, 자원을 이전 단계에서 전달받기만 하면 되는 것이다. 이러한 시스템을 개발할 경우 각각의 라인은 별도의 스레드를 통해서 구현될 것이다.
이처럼 스레드가 상호간에 데이터를 주고 받으면서 동시에 데이터를 생성되는 순서에 따라서 스레드의 실행을 제어해야 하는 경우 파이프 스트림을 사용하면 된다.


<java.nio.channels>
파일 및 소켓과 같이 I/O작업을 수행할 수 있는 엔터티에 대한 연결을 나타내는 채널을 정의합니다. 멀티플렉싱 된 비블로킹 I/O작업을 위한 선택기를 정의합니다.

<com.klab>
오픈 소스인 것 같은데..
일단 회사는 주로 소셜 비즈니스, 시스템 통합 비즈니스 및 클라우드 및 라이센스 비즈니스에 종사하는 회사이다. 소셜 부문은 소셜 네트워킹 서비스 제공 업테를 통한 게임 응용 프로그램곽 타은 소셜 애플리케이션 제공에 종사하고 있다. SI 부무은 음악, 전자 출판 및 오락 사업을 전문으로 하는 회사 고객을 위한 대규모 시스템 통합 서비스 제공에 종사하고 있다.

액션이 com.klab.svc.BaseAction 클래스를 상속받아 만든다.

https://m.blog.naver.com/PostView.nhn?blogId=kokolisy&logNo=110121503035&proxyReferer=https%3A%2F%2Fwww.google.com%2F
<for(A:B)>
B에서 차례로 객체를 꺼내서 A에 넣겠다. B가 없을 때까지


<javax.sound.sampled.clip>
clip인터페이스는 오디오 데이터가 실시간으로 스트리밍되는 대신 재생 전에 로드될 수 있는 특별한 종류의 데이터 라인을 나타냅니다.
데이터가 미리 로드되어 있고 길이가 알려지기 때문에 오디오 데이터의 어느 위치에서나 클립이 재생되도록 설정할 수 있습니다. 클립을 재생할 때 반복적으로 반복되도록 루프를 만들 수도 있습니다. 루프는 시작 및 끝 샘플 프레임과 루프가 재생되어야하는 횟수로 지정됩니다.
이 타입의 라인을 지원하는 Mixer로부터 클립을 취득할 수 있습니다. 클립이 열릴 때 클립에 데이터가 로드됩니다.

<javax.sound.sampled.AudioSystem>
샘플링 된 오디오 시스템 자원의 엔트리 포인트로서 기능한다. 이 클래스를 사용하면 시스템에 설치된 믹스를 쿼리하고 액세스할 수 있다. AudioSystem에는 오디오 데이터를 여러 형식으로 변환하고 오디오 파일과 스트림을 서로 변환하는 여러 가지 방법이 있습니다. 또한 믹서를 명시적으로 처리하지 않고 직접 Line을 얻는 방법을 제공합니다.

<java.net.HttpURLConnection>
HTTP고유 기능을 지원하는 URLConnection. 각 HttpURLConnection 인스턴스는 단일 요청을 만드는 데 사용되지만 HTTP 서버에 대한 기본 네트워크 연결은 다른 인스턴스에서 투명하게 공유될 수 있습니다.
요청 후에 HttpURLConnection의 InputStream 또는 OutputStream에서 close메서드를 호출하면 이 인스턴스와 고나련된 네트워크 리소스를 확보할 수 있지만 공유된 영구 연결에는 영향을 미치지 않습니다. disconnect메서드를 호출하면 영구 연결이 그 시간에 유휴 상태 인 경우 기본 소켓을 닫을 수 있습니다.

<java.net.URLConnection>
어플리케이션과 URL 사이의 통신 링크를 나타내는 모든 클래스의 슈퍼 클래스이다. 이 클래스의 인스턴스는 URL에서 참조하는 리소스를 읽고 쓰는데 사용할 수 있다. 일반적으로 URL에 대한 연결을 만드는 것은 다단계 프로세스이다.

http://arabiannight.tistory.com/entry/301
<instanceof 연산자>
참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 instanceof 연산자를 사용한다. 주로 조건문에 사용되며, instanceof의 왼쪽에는 참조변수를 오른쪽에는 타입(클래스명)이 피연산자로 위치한다. 그리고 연산의 결과로 boolean이 반환된다.
true를 얻었다는 것은 참조변수가 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.

<org.slf4j>
로깅 Facade이다. 로깅에 대한 추상 레이어를 제공하는 것이고 java로 따지면 interface덩어리라고 보면 된다. arifact이름도  api라고 부른다.

<targetDatsLine>
대상 데이터 라인은 오디오 데이터를 읽을 수있는 DataLine 유형입니다. 가장 일반적인 예는 오디오 캡처 장치에서 데이터를 가져 오는 데이터 라인입니다. (장치는 대상 데이터 행에 쓰는 믹서로 구현됩니다.)

<javax.sound.sampled.AudioFormat>
AudioFormat는, 사운드 스트림 내의 특정의 데이터 배치를 지정하는 클래스입니다. 오디오 포맷에 저장된 정보를 검토함으로써 바이너리 사운드 데이터의 비트 해석 방법을 발견 할 수 있습니다.
모든 데이터 라인은 데이터 스트림과 관련된 오디오 포맷을 가지고 있습니다. 소스 (재생) 데이터 라인의 오디오 포맷은 데이터 라인이 출력을 위해 어떤 종류의 데이터를 수신 할 것인지를 나타냅니다. 대상 (캡처) 데이터 행의 경우 오디오 형식은 행에서 읽을 수있는 데이터의 종류를 지정합니다. 물론 사운드 파일에도 오디오 형식이 있습니다. AudioFileFormat 클래스는, 다른 파일 고유의 정보에 가세 해 AudioFormat를 캡슐화합니다. 같이, AudioInputStream에는 AudioFormat가 있습니다.

http://egloos.zum.com/killins/v/3013974
<JSON>
JavaScript Object Notation이라는 이름에서 알 수 있듯이 자바스크립트를 위한 것이고 객체 형식으로 자료를 표현하는 것이다.
JSON 자체는 단순히 데이터 포맷일 뿐이다. 어떠한 통신 방법도 프로그래밍 문법도 아닌 단순히 데이터를 표시하는 표현 방법일 뿐이다. 간단한 데아터를 xml보다 좀 더 간단하게 표현하기 위해 만든 것이다. XML보다 기능이 적기 때문에 파싱도 빠르고 간단하기 때문에 클라이언트 사이드에서 특히, 모바일에서 더욱 유용하다. 사실 서버 입장에서도 더 유용하기 때문에 많은 서비스들이 XML보다는 JSON을 권장한다.
다시 말하지만 이건 프로그래밍 언어가 아니다.

이거 왜 쓰나?
단순히 데이터를 받아서 객체나 변수로 할당해서 사용하기 위한 것이다.

AJAX와는 다른가?
별개의 개념이지만 AJAX가 없다면 JSON이라는 개념은 필요 없을 것이다. AJAX를 사용해 데이터를 주고받을 때 그 데이터 포맷으로 JSON을 사용하는 것이다.

이거 쓰려면 따로 라이브러리 같은 걸 써야 하나?
이미 자바스크립트 표준으로 채택되어 자바스크립트에서 기본적으로 지원하고 있기 때문에 별도의 라이브러리가 필요하거나 하지는 않는다. 그냥 eval()이라는 함수 하나로 해결되는 게 JSON이다. 하지만 JSON의 한계로 인해 라이브러리를 따로 사용하는 경우가 많다. 그리고 자바스크립트 이외의 환경에서도 JSON을 간단히 사용하기 위한 라이브러리들이 존재한다. JSON 공식 사이트 내용의 대부분이 바로 그것이다.
-----------------------------------------------------------------------------------------------
http://1004lucifer.blogspot.com/2015/04/javagson-gson-java-json.html
http://yoo-hyeok.tistory.com/36

json은 주로 서버에서 클라이언트에게 값을 전달해주는 목적으로 사용됩니다. 특정 키 값과 value 값을 가지는 형태로 되어있으며 java의 hashMap이 여러 개 있는 형태와 비슷하게 구성됩니다.
'서버에서 클라이언트에게 값을 전달하는데 json말고 내가 원하는 문자 형태로 parsing하여 사용해도 되나요?'라는 질문에 답변을 하자면 저도 같은 생각을 하였고 얼마전에 json말고 문자 '%', '%'. '@' 등등 특정 문자 값으로 split 하여 사용했던 기억이 있습니다. 간단한 형태의 값들은 다음과 같은 문자를 사용해도 크게 지장은 없습니다. 하지만 데이터의 수가 많아지게 되면 특수 문자의 개수는 한정되어 있고 추가하기 위해서는 특수문자가 어떤 것을 쪼개어 주는지까지 외우고 있어야 합니다.


http://www.codejs.co.kr/mqtt-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0/
<MQTT>
Message Queuing Telemetry Transport란, 텔레메트리 장치, 모바일 기기에 최적화된 라이트 메시징 프로토콜입니다.
더 다양한 앱과 서비스의 등장으로 HTTP 등의 기존 프로토콜만으로는 커뮤티케이션의 다양한 요구사항을 수용할 수 없게 되었고, 제한된 통신 환경을 고려하여 디자인된 MQTT 프로토콜은 모바일 영역의 진화에 따라 최적의 프로토콜로 주목 받고 있습니다.

MQTT 프로토콜 설계의 의도
-프로토콜이 차지하는 모든 면의 리소스 점유를 최소화
-느리고 품질이 낮은 네트워크의 장애와 단절에 대비
-클라이언트 애플리케이션 동작에 자원 활용이 극히 제한적임을 고려
-다수의 클라이언트 연결에 접합한 publish/subscribe 네트워크 채용
-신뢰성 있는 메시징을 위한 QoS 옵션 제공.
-개방현 표준 메시징 프로토콜을 지향

주요 특징
-IBM과 Eurotech에 의해 1999년 최초 개발
-센서/장치 + 모바일 기기들의 연결을 위한 프로토콜
-MQTT 프로토콜 오픈소스로 공개
-단순하고 미니멀한 Pub/Sub 메시징 체제
-오버헤드를 최소화
-pub/sub에 있어서 메시징 신뢰성을 위한 세가지 QoS 레벨 제공
-클라이언트와 서버간의 연결을 잃었을 때 이를 보정하기 위한 자체 기능
-서버 측에서 연결의 유실 여부 인지
-세션 종료 후 재접속 시에도 재작업 없이 pub/sub 유지
----------------------------------------------------------------------------------------------
https://www.eclipse.org/paho/files/javadoc/org/eclipse/paho/client/mqttv3/MqttMessage.html
http://bananawabanana.blogspot.com/2017/08/java-mqtt.html
java로 보낸 메시지, 실시간으로 웹으로 받기(mqtt사용)

https://www.eclipse.org/paho/files/javadoc/org/eclipse/paho/client/mqttv3/persist/MemoryPersistence.html
<MemoryPersistence>
메모리를 사용하는 지속성 클라이언트 또는 장치가 메모리를 다시 시작할 때 안정성이 필요하지 않은 경우 이 메모리 일관성을 사용할 수 있습니다. 클린세션이 false로 설정될 때처럼 신뢰성이 요구되는 경우, 비휘발성 형태의 영속성이 사용되어야 합니다.


https://www.eclipse.org/paho/files/javadoc/org/eclipse/paho/client/mqttv3/MqttConnectOptions.html#setCleanSession-boolean-
<MqttClient>
조작이 완료될 때까지 블록하는 메소드를 사용하여 MQTT 서버와 통신하기 위한 경량 클라이언트

setCleanSession
-클라이언트와 서버가 재시작 및 재 연결시 상태를 기억하도록 설정합니다.
-true, 클라이언트와 서버는 클라이언트, 서버 또는 연결의 재시작시 상태를 유지하지 않습니다. 이것은
 -클라이언트, 서버 또는 연결을 다시 시작하면 지정된 QOS 로의 메시지 배달을 유지할 수 없습니다.
 -서버는 구독을 비영구적으로 취급합니다.


http://www.hardcopyworld.com/gnuboard5/bbs/board.php?bo_table=lecture_iot&wr_id=26&sfl=wr_subject%7C%7Cwr_content&stx=mqtt&sop=and
<MQTT>
센서장치나 라즈베리파이 같은 임베디드 장치, 모바일 장치 사이의 통신을 위한 가벼운 메시징 프로토콜입니다. TCP/IP 기반으로 대역폭이 작은 네트워크에서 동작할 수 있도록 설계된 프로토콜입니다. 쉽게 얘기해서 임베디드 장치들을 위한 트위터라고 볼 수 있습니다.
자체는 메시지를 어떻게 보낼 것인지를 정의하는 규약일 뿐입니다. 따아서 실제 'MQTT 트위터'를 동작시키기 위해서는 서버 역할을 해주는 장치와 프로그램이 필요한데 이를 MQTT 브로커(Broker)라고 합니다. 브로커는 각종 장치들(MQTT Client)이 보내주는 메시지를 수집하고 이걸 다시 필요한 장치들에게 전송해주는 중계서버 역할을 합니다.
클라이언트는 브로커에게 메시지를 전달하거나 필요한 메시지를 받기만 하면 되고, MQTT 프로토콜의 구조도 간단하기 때문에 처리능력이 낮은 임베디드 장치에 잘 어울립니다. 메시지는 트위터처럼 140자 제한이 없으므로 긴 메시지나 JSON 프멧 또는 파일도 전송이 가능합니다. 이런 특징들 때문에 MQTT 프로토콜은 센서 네트웍을 구성하는데 유용한 도구로 관심을 받고 있습니다.

동작구조
트위터 서비스의 동작구조를 떠올려보세요. 트위어에서 사용자는 다른 사용자를 follow할 수 있습니다. 그럼 다른 사용자가 생성하는 메시지(트윗)을 받아볼 수 있죠. 그리고 스스로 메시지를 생성할 수도 있습니다. 그럼 자신을 follow하는 사용자에게 메시지가 전덜되죠.
MQTT도 거의 유사한 동작구조를 갖습니다. MQTT 시스템에 참여하는 MQTT 클라이언트는 메시지 발행(publish, 트윗에 해당), 메시지 구독(sybscribe, follow에 해당) 두 가지 동작을 할 수 있습니다. MQTT 클라이언트가 메시지를 특성 채널(Topic, 토픽)에 발행하면 이 채널을 구독한 모든 클라이언트에게 메시지가 전달되는 겁니다. 중간에서 메시지를 수집, 재분해하는 작업은 MQTT 브로커가 담당합니다.

TOPIC(토픽)
메시지를 발생/구독(pub/sub)하는 행위는 채널 단위로 일어납니다. 이를 MQTT에서는 토픽(Topic)이라고 합니다. 토픽은 슬래시로 구분된 계층구조를 갖습니다.
메시지를 구독/발행할 때 여러개의 토픽을 한번에 지정할 수 있도록 wild card 문자를 지원합니다. [+]문자는 단 1개의(1의 레벨) 토픽을 임의의 토픽으로 대체하는 와일드카드 문자입니다.
반명 [#]문자는 여러 레벨의 토픽을 대체할 수 있습니다. [myhome/#]처럼 사용하면 myhome의 하위 토픽들 모두를 지칭하게 됩니다. [#] 문자는 토픽 문자열 끝에만 사용할 수 있으며 하위 토픽 모두를 지칭합니다.(2단계 이상 하위 토픽도 포함)
[$] 문자로 시작하는 토픽은 시스템에 의해 사용되는 특수한 토픽을 의미합니다. 이 토픽들은 [#] 문자열로 지정해도 포함되지 않는 토픽이 됩니다. 주로 [$SYS/] 로 시작하는 토픽들이 브로커의 내부 메시지를 위해 사용됩니다. (이에 대한 명확한 표준은 없는 상태인듯)

토픽 구조를 구성할 때 몇 가지 주의할 점이 있습니다.
-최상위 토픽이 [/] 문자로 시작하지 않도록 합니다. [/home/sensor/humid] 이렇게 사용할 수는 있지만 최상위 토픽이 이름이 없는 토픽이 되므로 사용하지 않는 것을 권장합니다.
-토픽 이름에 공백을 사용하지 않습니다.
-토픽 이름은 ASCII 문자만 사용합니다. (임베디드 장치와의 호환성을 위해 주의)
-[#] 를 이용해서 토픽 전체를 구독하지 않도록 합니다. 오버헤드가 심할 경우 브로커/클라이언트 프로세스가 중단될 수 있습니다.

QoS (Quality of Service)
MQTT는 시스템에 참여하는 장치들의 처리 능력, 네트워크 대역폭, 메시지 오버헤드 등 주변상황에 맞게 시스템이 동작할 수 있도록 3단계 QoS(Quality of Service) 를 제공합니다.
-0 : 메시지는 한번만 전달하며, 전달여부를 확인하지 않는다. Fire and Forget 타입이다.
-1 : 메시지는 반드시 한번 이상 전달된다. 하지만 메시지의 핸드셰이킹 과정을 엄밀하게 추적하지 않기 때문에, 중복전송될 수도 있다.
-2 : 메시지는 한번만 전달된다. 메시지의 핸드셰이킹 과정을 추적한다. 높은 품질을 보장하지만 성능의 희생이 따른다.

0에 가까울수록 메시지 처리에 대한 부하가 적은 대신 메시지 손실 위험이 높아집니다. 2에 가까울수록 메시지 손실 위험은 줄어들지만 메시지 처리 부하가 급격히 늘어납니다.
(보통 0~1 정도의 QoS를 사용하면서 메시지 손실등의 위험은 상위 어플리케이션 차원에서 관리하도록 하는듯 합니다.)

MQTT 브로커 설치
브로커는 시스템의 핵심 서버 역할을 하며, 여기에 메시지가 수집되고 다시 재분배됩니다. 다양한 MQTT 브로커 프로그램들이 개발되어 있는데 ActiveMQ, Apollo, IBM Message Sight, JoramMQ, Mosqutto, RabbitMQ, Solace Message Routers 등이 자주 사용됩니다. 아래 링크에 MQTT 브로커의 특징을 비교한 자료가 있습니다.

-https://github.com/mqtt/mqtt.github.io/wiki/server-support

여기서는 Mosquitto 브로커를 사용할 것입니다. Mosqutto는 MQTT의 기능을 충실히 지원하는 가벼운 MQTT 브로커 프로그램입니다. Mosquitto 클라이언트 프로그램도 있으므로 여러대의 PC를 이용해서 테스트를 할 수 있습니다.

MQTT 동작 테스테를 위해 라즈베리파이에 Mosquitto MQTT 브로커를 설치하고 PC 및 모바일 폰에는 MQTT 클라이언트를 설치할 것입니다.

라즈베리파이에 Mosquitto 브로커를 설치하는 작업부터 시작합니다. Mosquitto는 apt-get 명령어를 통해 간단히 설치할 수도 있지만 업데이트가 되지 않는 문제점이 보고되고 있습니다. 아래 순서로 설치하길 권장합니다.(최신 소스 코드를 다운로드 받아 설치하실땐 링크를 참고하세요.)

설치가 완료되면 브로커는 1883 포트를 사용하게 됩니다.

이제 PC와 모바일 폰에 MQTT 클라이언트를 설치해서 연동을 해보겠습니다. PC(Windows, Linux, OS X)에서는 MQTT.fx 클라이언트를 설치하면 됩니다. 아래 링크에서 프로그램을 받을 수 있습니다.

MQTT.fx 클라이언트는 윈도우 64비트만 지원합니다. 이 문제 때문에 설치가 안된다면 크롬 브라우저의 확장 앱으로 설치해서 사용하는 방법도 있습니다. 크롬 브라우저에서 아래 링크를 통해 설치할 수 있습니다.

모바일 폰에서는 앱 스토어에서 MQTT로 검색하시면 됩니다. 다양한 클라이언트가 등록되어 있는데 대부분 비슷하므로 아무거나 사용하셔도 됩니다. 유명한 MQTT 클라이언트들은 링크에서 확인하실 수 있습니다.

설정 방법은 간단합니다. 일단 MQTT 브로커 연결을 위해 아래 항목들만 정확히 설정해 주면 됩니다.
-MQTT 브로커 URL: MQTT 브로커를 설치한 서버의 URL입니다.
 -같은 공유기에 PC, 모바일 폰, 라즈베리파이가 같이 물려있다면 라즈베리파이의 내부 IP주소(192.168.x.x)를 사용하면 됩니다.
-Port: 앞서 설치한 Mosquitto 브로커는 기본 1883 포트를 사용합니다.
-Username/Password: 지금은 설정하지 않아도 됩니다.

그리고 우리가 메시지를 받을 Topic을 지정해주면 이후 해당 Topic으로 들어오는 메시지를 볼 수 있습니다. MQTT 클라이언트에서 subscribe 버튼을 누르고 토픽에 messagebox를 입력합니다. 그럼 messagebox 토픽이 생성되고 구독이 됩니다. PC, 모바일 등 모든 장치에서 같은 작업을 해줍니다.
이제 PC, 모바일에서 publish를 합니다. 이때 토픽은 messagebox로 선택합니다. 그럼 입력한 메시지가 브로커로 전달되고 messagebox 토픽을 구독하는 다른 장치들에도 전달되어야 합니다. 제대로 동작하는지 확인해보세요.

MQTT 브로커를 설치한 라즈베리파이에 MQTT 클라이언트를 설치해서 확인할 수도 있습니다.
-apt-get install mosquitto-clients

아래 명령으로 메시지 발행(pub)을 할 수 있습니다. 다른 기기에도 메시지가 보여야겠죠.
-mosquitto_pub -d -t messagebox -m "sent from RPi server"

특정 토픽을 구독(sub)할 수 있습니다. 이 경우 특정 토픽에 메시지가 도착할 때마다 표시됩니다. Ctrl+C를 눌러 멈추기 전까지는 메시지 표시하는 상태로 유지됩니다.
-mosquitto_sub -d -t messagebox


센서장치와 MQTT
이제 센서장치에 MQTT client 기능을 넣어서 데이터를 뿌리면 PC-서버-모바일 폰 등 다양한 장치들이 메시지를 수신할 수 있겠죠?
센서장치에 MQTT 기능을 넣기 위해서는 라이브러리 설치가 필요합니다. 아두이노 개발환경을 실행해서 [메뉴-스케피치-라이브러리 포함하기-라이브러리 관리] 를 순서대로 실행합니다. 그리고 PubSubClient로 검색하세요. 발견된 라이브러리 중 PubSubClient 라이브러리를 설치하면 됩니다.

<팩토리 패턴>
super class와 여러 개의 sub class가 있는 상황에서 input이 발생하면 하나의 sub class를 반환해야 할 때 사용된다. factory class는 client class로부터 인스턴스를 생성하는 책임을 가져온다.
객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 인스턴스를 만들지는 서브클래스에서 결정하게 만든다. 즉, 팩토리 메소드 패턴을 이용하면 클래스의 인스턴스를 만드는 일을 서브클래스에게 맡기는 것

<swing>
자바에서 GUI를 구현하기 위해 JDK에서 기본적으로 제공하는 개발 툴킷으로 선 마이크로시스템즈의 자바 기반 클래스의 일부이다.
스윙은 기존에 발표되었던 AWT가 OS 및 윈도 시스템의 자원을 그대로 제공하기 때문에 자바에서 지향하는 "Write Once, Run Everywhere(WORE)"를 구현하기 위해 각종 시스템에서 공통적으로 제공하는 버튼, 대화창 등만을 구현하고 표나 트리 등의 좀 더 복잡하고 다양한 그래픽 컴포넌트를 사용할 수 없는 단점을 보완하기 위하여 JDK 1.2 버전부터 사용되었다.


http://shuming.tistory.com/entry/java%EC%97%90%EC%84%9C-JNI-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-c-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%ACsodll-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0

linux에서는 so 파일을 쓸 수 있다.
.so 파일은 c 라이브러리 파일이다.

1. .so 파일 만들기
1) c파일 생성
이 놈을 컴파일해서 so로 만듦

http://wowan.tistory.com/115

2) java h 파일 만듦
그리고 컴파일합니다.
$ javac HelloWorld.java
그리고 javah를 이용해서 HelloWorld.h를 만듦
$javah HelloWorld
c 파일을 보면 java의 클래스명을 include하고 있고, 함수명 또한 맞춰야 한다.

그런데 함수명이 Java_HelloWorld_print(~) 라고 해서 저걸 다 쓰는게 아니고 그냥 print만 쓰면 된다.

3) gcc를 통해서 빌드
빌드하고나면 so 파일이 생긴다.

2. Linux 환경에서 .so 파일을 핸들링 하는 방법.

*HelloWorld.c
#include <stdio.h>
#include "HelloWorld.h"

JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj){
    printf("Hello World");
}

*HelloWorld.java
class HelloWorld{
    static{
        System.loadLibrary("Hello");
    }

    public native void print();
}
->javah HelloWorld로 .h 파일을 만듦

*HelloWorld.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __ cplusplus
extern "c" {
#endif
/*
 * Class:     HelloWorld
 * Method:    print
 * Signature: ()V
 */

JNIEXPORT void JNNICALL Java_HelloWorld_print
    (JNIEnv*, jobject)

#ifdef __cplusplus
#endif

->이제 만들어진 헤더파일로 gcc를 통해 HelloWorld.c를 빌드한다.
->.so 파일이 생성된다.

이제 저 라이브러리를 불러오고 있는 HelloWorld.java 가 이미 있으니까 저걸 불러다가 print() 를 가져온다.


http://adnoctum.tistory.com/541
so 파일은 shared object 파일이란 뜻으로, *.so.* 일텐데, 특정한 기능을 구현해 놓은 파일을 의미한다. 즉, 프로그램들은 일반적으로 필요한 기능을 전부 구현하기보다는 특정 기능이 이미 구현되어 있으면 그 기능이 구현된 파일을 메모리에 올린 후 그 기능을 사용하게 된다.
그래서, 만약 내가 설치하고자 하는 파일이 특정 기능 때문에 어떤 so 파일이 필요하다고 할 때, 어떤 경우는 설치시 so 파일 존재 여부를 확인해 보거나, 어떤 경우는 설치된 이후 실제 so 파일에 구현된 기능이 필요할 때 메모리에 올리기 위해 그 so 파일을 찾다가 없어서 에러가 날 때도 있다. 그런 경우 주로 다음과 같은 에러 메세지가 나타난다.
왜 저런 말이 나타냤느냐 하면, 일반적으로 so 파일을 어디에서 찾아야 하는지를 설정해 놓은 경로를 모두 찾아 보았음에도 불구하고 libstdc++.so.5 와 libgcc_s.so.1 파일을 찾을 수 없었기 때문이다. 물론 저 파일이 실제로 어딘가에 있기 때문에, 심지어 현재 경로에 있기 때문에 대체 왜 저런 에러가 나타났을까 의아해 할 수도 있는데, so 파일은 그것과 상관이 없이 다음과 같은 순서로 경로들을 순회하면서 찾게 되고, 그렇게 돌았던 경로에서 찾지 못하면 위와 같은 에러 메세지가 나타난다.
*so 파일을 찾는 경로 설정
1. system default 경로
2. LD_LIBRARY_PATH
3. binary code 에 hard-coding 된 경로


https://m.blog.naver.com/PostView.nhn?blogId=dae0park&logNo=221040790681&proxyReferer=https%3A%2F%2Fwww.google.com%2F

http://unabated.tistory.com/entry/Maven-%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%83%9D%EC%84%B1-%EB%B0%8F-%ED%99%9C%EC%9A%A9
<Maven 활용법>
*pom.xml
dependencies 항목은 어플리케이션을 컴파일하고, 테스트하고, 실행하는데 필요한 라이브러리 목록을 기술합니다.
dependency 설정을 통해 의존관계에 있는 라이브러리를 추가할 수 있습니다.
프로젝트 정보와 별도 항목으로 빌드(build) 설정, plugin 설정, 빌드환경정보, pom의 연관정보 (의존프로젝트, 상위 하위 모듈등), 리포팅(checkStyle 등을 이용) 등의 주요 항목들을 기술하게 되어있습니다.

-프로젝트 정보 항목
 -name: 프로젝트의 이름
 -url: 사이트 URL

-프로젝트 연관 정보
 -groupId : 프젝트 그룹 ID, 도메인이나 특정한 정보로 식별.
 -arrifactId: 프로젝트 Artifact ID 설정, 프로젝트에 의해 생성되는 Artifact 명 -version.packaging 의 형태로 Artifact 파일이 생성
 -version: 버전 설정. 여기서는 SampleApp-0.0.1-SNAPSHOT.jar 가 되는데 0.0.1-SNAPSHOT이 version이 됨.
 -packaging: 패키징 타입 설정. 여기서는 jar 파일로 생성됨을 의미. jar 뿐만 아니라 웹 어플리케이션을 위한 war나 JEE를 위한 ear 등의 패키징 타입을 지정할 수 있음.

-dependencies : 이 프로젝트에서 의존하는 다른 프로젝트 정보를 기술.
 -dependency : 의존하는 프로젝트 POM 정보를 기술
  -groupId : 의존하는 프로젝트의 그룹 ID
  -artifactId : 의존하는 프로젝트의 artifact ID
  -version : 의존하는 프로젝트의 버전
  -scope : 의존하는 범위 (compile, runtime, provided, test 로 scope 가 나뉨)

http://namocom.tistory.com/182
닷넷에서는 애플리케이션의 설정을 외부에서 설정하기 쉽게 하기 위해서 설정파일을 이용할 수 있게 되어 있다.
이름은 app.config/web.config 등 다양하다.

댓글 없음:

댓글 쓰기