30 Oct 2014, 03:38

iPhone を CIFS サーバにするアプリ CIFS NQ

仕事で CIFS をつかっている.

たとえば, カフェでダラダラしているときに, 急に CIFS のパケットが気になってしょうがなくなったとしよう.

NotePC には Windows がはいっている. しかし, Windows のクライアントがあっても接続する CIFS サーバがないと, CIFS のパケットを見ることができない!

VirtualBox に CentOS を入れて, その上に Samba サービスを立ち上げるとい うことを以前やった.

しかし, 今は仮想マシンを立ち上げる容量がないという不幸な状況.

そんなもどかしさに悶え苦しんでいるひとのために朗報!

iPhone を CIFS サーバにすればよい

iPhone を CIFS サーバにするアプリ

GoodReader

<div class="outline-text-3" id="text-1-1">
  <p>
    仕事効率化の定番アプリ, GoodReader に エクスプローラからアクセスする ことができる.以下, リンク参照.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://samulife.com/iPhone/goodreader-webdav">iPhone GoodReader を PC のネットワークドライブに割り当てる方法!! ドラッグ&ドロップでファイル転送できる</a>
    </li>
  </ul>

  <p>
    しかし, この手順で Windows のエクスプローラからアクセスすると, 都合が わるいことに気づく.それは, GoodReader のサポートしている SMB のバージョ ンが 1 だったこと.
  </p>

  <p>
    自分は, SMB2 のパケットが見たかった&#x2026;.
  </p>
</div>

CIFS NQ

<div class="outline-text-3" id="text-1-2">
  <p>
    ということで, 次に探したのがこれ. CIFS NQ.
  </p>

  <ul class="org-ul">
    <li>
      <a href="https://itunes.apple.com/jp/app/id806015001">iTunes の App Store で配信中の iPhone, iPod touch, iPad 用 CIFS NQ</a>
    </li>
  </ul>

  <p>
    開発した会社は, CIFS/SMB のリーディングカンパニーとか.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://www.visualitynq.com/?lang=jp">Visuality Systems &#8211; ホーム</a>
    </li>
  </ul>

  <p>
    無料なので, さっそくインストールしてみた. 設定画面からサーバステータスを ON に設定することで, CIFS サーバ起動.
  </p>

  <p>
    エクスプローラの URL 欄に IP を打ち込んで乗り込む. WireShark でパケッ トキャプチャをすると, SMB2 だった.
  </p>

  <p>
    おもわずニヤリ.
  </p>

  <p>
    これで, カフェで SMB2 のパケットをみることができるよになった.
  </p>
</div>

さいごに

誰トクな記事なんだろう….

29 Oct 2014, 13:29

数学での関数とプログラミングでの関数

関数についての違和感

大学では, 応用数学を専攻していた.

大学でならった関数の定義は, ある集合から別の集合への写像だった.

就職して, C 言語でプログラムを書くようになってからずっと, どうも関数にたいして違和感を抱いてきた.

なんでこれが関数なんだ??

int main (void) {
  printf ("Hello, World!");
  return 0;
}

以下のページに同じようなことがかかれていたので引用.

x = x + 1

古き良き小学校の時代, この行には困惑させられたものだった. 魔術的な x が, 加算されたのに等しいままでいる事に. どういうわけか, プログラミングを始めると, それに構わなくなる. 「やれやれ, それは重大な事柄じゃないし, プログラミングとは現実のビジネス行為なんだから, 数学的な純粋さについてあら探しなんて必要無い (その議論なら, 大学にいる狂った髭面野郎どもにさせておけばいい) 」と思っていた. けれども, ただ知らなかっただけで, 我々が間違っていて高い代償を支払っていたのは 明らかである.

Haskell における関数の定義

最近, プログラミング Haskell という本を読んだ.

その中での関数の定義を読み, 自分が思ってきた関数のイメージと一致した.

関数は, ある型の引数を他の型の引数の結果に変換する. 型とは, 互いに関連する値の集合.

これだ! と思った.

これが大学でならった関数の定義だ. 関数型言語というのは数学に近いときいていたが, それを感じた瞬間だった.

うれしかったので, 今回の記事にしてみた. もっと, 関数型言語について知りたいと思った.

C 言語と Java における関数の定義

C 言語 (手続き型) と Java (オブジェクト指向型) における関数の定義について も, Wikipedia で調べてみたので, 書いておく.

関数型における関数とは, 意味するところは違う. これが, 違和感の正体だった.

C 言語 (手続き型パラダイム)

戻り値つきのサブルーチン.

プログラム中で意味や内容がまとまっている作業をひとつの手続きとしたもの.

Java (オブジェクト指向パラダイム)

あるクラスないしオブジェクトに所属するサブルーチン.

各オブジェクトが持っている自身に対する操作. オブジェクトは「データ」と「手続き」から成っているが, その「手続き」の部分に当たる.

22 Oct 2014, 14:52

Haskell を快適に利用するための Emacs 環境の構築

edX で Haskell の講座をとり始めました.

内容はさておき, まずは Emacs の環境作りから始めました.

環境づくりに夢中になって内容がおろそかになるという, いつもの悪いパターン.

haskell-mode

Haskell のマイナーモード.

(autoload 'haskell-mode "haskell-mode" nil t)
(autoload 'haskell-cabal "haskell-cabal" nil t)

(add-to-list 'auto-mode-alist '("\\.hs$" . haskell-mode))
(add-to-list 'auto-mode-alist '("\\.lhs$" . literate-haskell-mode))
(add-to-list 'auto-mode-alist '("\\.cabal\\'" . haskell-cabal-mode))

モードの設定.以下のリンクが詳しい.

 ;; indent の有効.
(add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
(add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode)
(add-hook 'haskell-mode-hook 'font-lock-mode)
(add-hook 'haskell-mode-hook 'imenu-add-menubar-index)

Haskell Script の編集モード

(add-to-list 'interpreter-mode-alist '("runghc" . haskell-mode))
(add-to-list 'interpreter-mode-alist '("runhaskell" . haskell-mode))

Haskell でかかれたスクリプトを haskell-mode で編集する.

#!/usr/bin/env runhaskell

Ghci との連携

M-x run-haskell で ghci が起動.

(setq haskell-program-name "/usr/bin/ghci")

C-c, C-l でも起動.

(add-hook 'haskell-mode-hook 'inf-haskell-mode) ;; enable

ghci の起動とファイルの読み込みを一緒に行う設定.

(defadvice inferior-haskell-load-file (after change-focus-after-load)
  "Change focus to GHCi window after C-c C-l command"
  (other-window 1))
(ad-activate 'inferior-haskell-load-file)

- inferior-haskell-mode で設定すると便利なこと - プログラムとかのの blog

gcd-mod

Haskell 開発を助ける機能がそろったツール.

Install

% cabal update
% cabal install ghc-mod

Settings

(autoload 'ghc-init "ghc" nil t)
(autoload 'ghc-debug "ghc" nil t)
(add-hook 'haskell-mode-hook (lambda () (ghc-init)))

Emacs での使い方は以下のページに書いてある.

エラーチェック

flymake

構文チェック.

(add-hook 'haskell-mode-hook (lambda () (flymake-mode)))

hlint

コードチェック. cabal install hlint でインストールする. C-c C-c でカーソル部のチェック.

自動補完

こんなの見つけた. ac-haskell-process.

(require 'ac-haskell-process) ; if not installed via package.el
(add-hook 'interactive-haskell-mode-hook 'ac-haskell-process-setup)
(add-hook 'haskell-interactive-mode-hook 'ac-haskell-process-setup)
(eval-after-load "auto-complete"
  '(add-to-list 'ac-modes 'haskell-interactive-mode))

Links

21 Oct 2014, 14:46

セマフォを利用して 2 つのスレッドに交互に処理をさせる方法 (Java)

Java の並列処理用のライブラリについて調べたまとめ. 主に, 先日受けた coursera の POSA の復習だったりします.

Semaphore

並列プログラミング環境での複数のプロセスが共有する資源に アクセスするのを制御する際の単純だが便利な抽象化を提供する変数または抽象データ型

2 種類に分けられる.

Counting Semaphores

カウンティングセマフォ. 任意個の資源を扱うセマフォ

Binary Semaphores

バイナリセマフォ. 値が 0 と 1 に制限されている (ロック/ アンロック, 使用可能/ 使用不可の意味がある) セマフォ.

ミューテックスともいう.

Java

ConditionObject

wait/notify によるスレッド間の通知では, 一つのスレッドで一ヶ所でしか wait できない.たとえば, 条件 A と条件 B の両方がそろうまでまつなど.

ConditionObject を利用すると, 複数箇所で wait することができる.

Condition は, Object 監視メソッド (wait, notify, および notifyAll) を別個のオブジェクトに分解し, それらに任意の Lock 実装の使用を組み合わせて, オブジェクトごとに複数の待機セットを保持する効果を付与します.

Java

CountdonwLatch

他のスレッドをある地点でまち合わせるための機構.

競馬のスタートバーのようなイメージ.

または, 旅行のツアーガイド. 集合時間が決められていてるので, それまでに旅行客は集合場所に集合する. 全員が集合したら, 次の移動場所へ移動する.

Java

PingPong

2 つのスレッドがセマフォを利用しつつ, 交互に処理をするプログラム.

セマフォ処理

import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.Condition;

public class SimpleSemaphore {
    private Lock lock;
    private Condition notEmpty;
    private volatile int count;

    public SimpleSemaphore (int permits, boolean fair) {
        count = permits;
        lock = new ReentrantLock (fair);
        notEmpty = lock.newCondition ();
    }

    public void acquire () throws InterruptedException {
        lock.lockInterruptibly ();
        try { 
            while (count == 0) 
                notEmpty.await ();
            count--;
        }finally{ lock.unlock (); }
    }

    public void acquireUninterruptibly () {
        lock.lock ();
        try { 
            while (count == 0) 
                notEmpty.awaitUninterruptibly ();
            count--;
        }finally{ lock.unlock (); }
    }

  public void release () {
        lock.lock ();
        try{ 
            count++;
            notEmpty.signal ();
        }
        finally{lock.unlock ();}
    }

    public int availablePermits () {
        return count;
    }
}

メイン処理

import java.util.concurrent.CountDownLatch;

public class PingPongRight {

    // イテレーション数
    public final static int mMaxIterations = 10;

    // 2 つのスレッドの待ちあわせ用
    public static CountDownLatch mLatch;

    public static class PlayPingPongThread extends Thread {

        private int mMaxLoopIterations = 0;
        String mStringToPrint;

        SimpleSemaphore mSemaphoreOne;
        SimpleSemaphore mSemaphoreTwo;

        public PlayPingPongThread (String stringToPrint,
                                                             SimpleSemaphore semaphoreOne, SimpleSemaphore semaphoreTwo,
                                                             int maxIterations) {
            mStringToPrint = stringToPrint;
            mSemaphoreOne = semaphoreOne;
            mSemaphoreTwo = semaphoreTwo;
            mMaxLoopIterations = maxIterations;
        }

        public void run () {

            for (int loopsDone = 1; loopsDone <= mMaxLoopIterations; ++loopsDone) {
                try {
                    // 処理の権利を取得して, 処理を実施
                    acquire ();
                } catch (InterruptedException e) {
                    e.printStackTrace ();
                }
                System.out.println (mStringToPrint + "(" + loopsDone + ")");
                // 次の処理の権利を解放
                release ();
            }

            // 自スレッドの処理がすべて終わったらカウントダウン
            mLatch.countDown ();
        }

        private void acquire () throws InterruptedException {
            mSemaphoreOne.acquire ();
        }

        private void release () {
            mSemaphoreTwo.release ();
        }
    }

    public static void process (int maxIterations) throws InterruptedException {
        // 待ち合わせ
        mLatch = new CountDownLatch (2);

        // バイナリセマフォ
        // セマフォを獲得できたら 次のステップに進める
        SimpleSemaphore pingSema = new SimpleSemaphore (1, true);
        SimpleSemaphore pongSema = new SimpleSemaphore (1, true);

        // pong が動作しないようにセマフォ獲得
        // これで, 確実に ping から処理をすすめることができる.
        pongSema.acquire ();

        // 二つのスレッド生成
        PlayPingPongThread ping = new PlayPingPongThread ("Ping! ",
                                                                                                            pingSema,
                                                                                                            pongSema,
                                                                                                            maxIterations);
        PlayPingPongThread pong = new PlayPingPongThread (" Pong!",
                                                                                                            pongSema,
                                                                                                            pingSema,
                                                                                                            maxIterations);

        System.out.println ("Go!");

        // スレッドスタート
        pong.start ();
        ping.start ();

        // 二つのスレッドの待ち合わせ
        mLatch.await ();

        System.out.println ("Done!");
    }

    public static void main (String[] args) throws InterruptedException {
        process (mMaxIterations);
    }
}

20 Oct 2014, 15:45

Java で Producer-Consumer Pattern を実装してみた

二つのスレッドで同期キューを用いて情報をやりとりするときに利用する アーキテクチャ・パターンに, Producer-Consumer Pattern というものがある.

Publisher-Subscriber パターン, 生産者-消費者パターンともいう.

これを Java で実装する場合は, BlockingQueue インターフェースを利用できる.

syncronised/wait/notify を利用してもできるが, BlockingQueue を利用したほうが楽.

以下, coursera の POSA での Assignment を改造してみて, 簡易版の Producer-consumer Pattern を書いてみた.

source

[sourcecode language=”java” title=”” ]
import java.util.concurrent.*;

public class SynchronizedQueue {
// Keep track of the number of times the producer test iterates.
static volatile int mProducerCounter = 0;

// Keep track of the number of times the consumer test iterates.
static volatile int mConsumerCounter = 0;

// Maximum timeout.
static final int TIMEOUT_SECONDS = 5;

// Error value for a timeout.
static final int TIMEOUT_OCCURRED = -1;

// Error value for a failure.
static final int FAILURE_OCCURRED = -2;

public static class QueueAdapter {
private BlockingQueue mQueue;

public QueueAdapter (BlockingQueue queue) {
mQueue = queue;
}

/**
* Insert msg at the tail of the queue.
*/
public void put (E msg) throws InterruptedException, TimeoutException {
// Keep track of how many times we’re called.
mProducerCounter++;
boolean timeoutValue = mQueue.offer (msg,
TIMEOUT_SECONDS,
TimeUnit.SECONDS);
if (timeoutValue == false)
throw new TimeoutException ();
}

/**
* Remove msg from the head of the queue.
*/
public E take () throws InterruptedException, TimeoutException {
// Keep track of how many times we’re called.
mConsumerCounter++;
E rValue = mQueue.poll (TIMEOUT_SECONDS,
TimeUnit.SECONDS);

if (rValue == null)
throw new TimeoutException ();

return rValue;
}
}

private static QueueAdapter mQueue = null;

static Runnable producerRunnable = new Runnable () {
public void run () {
for (int i = 0; i < mMaxIterations; i++) try { mQueue.put (i); if (Thread.interrupted ()) throw new InterruptedException (); } catch (InterruptedException e) { System.out.println ("Thread properly interrupted by " + e.toString () + " in producerRunnable"); // This isn't an error - it just means that // we've been interrupted by the main Thread. return; } catch (TimeoutException e) { System.out.println ("Exception " + e.toString () + " occurred in producerRunnable"); // Indicate a timeout. mProducerCounter = TIMEOUT_OCCURRED; return; } catch (Exception e) { System.out.println ("Exception " + e.toString () + " occurred in producerRunnable"); // Indicate a failure. mProducerCounter = FAILURE_OCCURRED; return; } } }; static Runnable consumerRunnable = new Runnable () { public void run () { for (int i = 0; i < mMaxIterations; i++) try { if (Thread.interrupted ()) { throw new InterruptedException (); } Integer result = (Integer) mQueue.take (); System.out.println ("iteration = " + result); } catch (InterruptedException e) { System.out.println ("Thread properly interrupted by " + e.toString () + " in consumerRunnable"); // This isn't an error - it just means that // we've been interrupted by the main Thread. return; } catch (TimeoutException e) { System.out.println ("Exception " + e.toString () + " occurred in consumerRunnable"); // Indicate a timeout. mConsumerCounter = TIMEOUT_OCCURRED; return; } catch (Exception e) { System.out.println ("Exception " + e.toString () + " occurred in consumerRunnable"); // Indicate a failure. mConsumerCounter = FAILURE_OCCURRED; return; } } }; // Number of iterations to test public static int mMaxIterations = 1000000; public static int mMaxQueueSize = (mMaxIterations / 10); public static void main (String[] args) { try { mQueue = new QueueAdapter(new ArrayBlockingQueue(mMaxQueueSize));
// mQueue = new QueueAdapter(new LinkedBlockingQueue ());

// create threads
Thread consumer = new Thread (consumerRunnable);
Thread producer = new Thread (producerRunnable);

// start the threads.
consumer.start ();
producer.start ();

// Give the Threads a chance to run before interrupting them.
Thread.sleep (100);

// interrupt the threads.
consumer.interrupt ();
producer.interrupt ();

// wait for the threads to exit.
consumer.join ();
producer.join ();

} catch (Exception e) {
}
}
}
[/sourcecode]

18 Oct 2014, 03:36

手続き型・オブジェクト指向型・関数型 3 つのパラダイムでステートパターン (Java)

はじめに

Java でステート・パターン (State Pattern) を実装してみた.

よく見かける OOP のステートパターンに加えて, 手続き型パラダイム, 関数型パラダイムのステートパターンも実装した.

そもそも, ステートパターンはオブジェクト指向において,状態をカプセル化することなので, 関数型で表現することはステートパターンではない気がするが…

OOP との比較をしたいので,手続き型, 関数型ともに , class を利用して状態をあらわした.

ステートパターンの詳しい説明は以下.

オブジェクト指向パラダイム

まずは, よく見かける表現.特徴は,

  • context は 状態 (state) をもつ.
  • 状態 (state) は context への参照を保持する.

[sourcecode language=”java” title=”” ]
class StatePatternImperative {
private State state;

public StatePatternImperative () {
this.state = new Morning ();
}

public void setState (State newState) {
this.state = newState;
}

public void greeting () {
state.greeting (this);
}

public boolean isDone () {
return (state == null) ? true : false;
}

public interface State {
public void greeting (StatePatternImperative context);
}

public class Morning implements State {

public Morning () {
System.out.println (” === It’s 09:00 ===”);
}

public void greeting (StatePatternImperative context) {
System.out.println (“Good morning!! (‘▽`)”);
context.setState (new Afternoon ());
}
}

public class Afternoon implements State {

public Afternoon () {
System.out.println (” === It’s 15:00 ===”);
}

public void greeting (StatePatternImperative context) {
System.out.println (“Good afternoon!! (‘▽`)”);
context.setState (new Evening ());
}
}

public class Evening implements State {

public Evening () {
System.out.println (” === It’s 20:00 ===”);
}

public void greeting (StatePatternImperative context) {
System.out.println (“Good evening!! (‘▽`)”);
context.setState (null);
}
}

public static void main (String[] args) {
StatePatternImperative context = new StatePatternImperative ();

while (!context.isDone ()) {
context.greeting ();
}
}
}
[/sourcecode]

手続き型パラダイム

次は手続き型. OOP との違いは,

  • 状態を保持する context はない.
  • 次の状態は戻り値で外部に返す.

[sourcecode language=”java” title=”” ]
class StatePatternImperative {

public interface State {
public State greeting ();
}

public static class Morning implements State {

public Morning () {
System.out.println (” === It’s 09:00 ===”);
}

public State greeting () {
System.out.println (“Good morning!! (‘▽`)”);
return new Afternoon ();
}
}

public static class Afternoon implements State {

public Afternoon () {
System.out.println (” === It’s 15:00 ===”);
}

public State greeting () {
System.out.println (“Good afternoon!! (‘▽`)”);
return new Evening ();
}
}

public static class Evening implements State {

public Evening () {
System.out.println (” === It’s 20:00 ===”);
}

public State greeting () {
System.out.println (“Good evening!! (‘▽`)”);
return null;
}
}

public static boolean isDone (State state) {
return state == null;
}

public static void main (String[] args) {
State state = new Morning ();

while (!isDone (state)) {
state = state.greeting ();
}
}
}
[/sourcecode]

main () を context とみなせば, OOP とも言えなくはないが…

関数型パラダイム

最後に関数型. 手続き型との違いは,

  • 再帰的に処理する (末尾再帰)

具体的には,以下の違いかある.

[sourcecode language=”java” title=”” ]
// functional paradium
public static void run (State state) {
if (isDone (state)) return;
else run (state.greeting ());
}

public static void main (String[] args) {
run (new Morning ());
}

// imperative paradium
public static void main (String[] args) {
State state = new Morning ();

while (!isDone (state)) {
state = state.greeting ();
}
}
[/sourcecode]

[sourcecode language=”java” title=”” ]
class StatePatternFunctional {

public interface State {
public State greeting ();
}

public static class Morning implements State {

public Morning () {
System.out.println (” === It’s 09:00 ===”);
}

public State greeting () {
System.out.println (“Good morning!! (‘▽`)”);
return new Afternoon ();
}
}

public static class Afternoon implements State {

public Afternoon () {
System.out.println (” === It’s 15:00 ===”);
}

public State greeting () {
System.out.println (“Good afternoon!! (‘▽`)”);
return new Evening ();
}
}

public static class Evening implements State {

public Evening () {
System.out.println (” === It’s 20:00 ===”);
}

public State greeting () {
System.out.println (“Good evening!! (‘▽`)”);
return null;
}
}

public static boolean isDone (State state) {
return state == null;
}

public static void run (State state) {
if (isDone (state)) return;
else run (state.greeting ());
}

public static void main (String[] args) {
run (new Morning ());
}
}
[/sourcecode]

18 Oct 2014, 01:53

Windows で Emacs を利用する

はじめに

Windows 上では, Cygwin でインストールした Emacs を今まで利用していたのだが, Cygwin の Emacs だと文字のレンダリングがズレルことがしばしばある.

さすがにイライラしてきたので, Windows 用の Emacs を入れてみることにした.

Emacs for Windows

Windows 用にコンパイルされた Emacs のバイナリが以下から手に入る. 32bit 用はあるけど, 64bit はみつからないな^^;. まあいいや. 最新版を取得する.

適当な所に解凍 (C:-24.3). bin フォルダの中にある runemacs.exe を起動して Emacs が立ち上がれば成功. runemacs.exe はデスクトップなどにショートカットを作成.

14/10/18 追記

<div class="outline-text-3" id="text-2-1">
  <p>
    Windows 版 64bit のバイナリを発見!
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://sourceforge.net/projects/emacsbinw64/?source=typ_redirect">emacs-w64 | SourceForge.net</a>
    </li>
    <li>
      <a href="http://emacsbinw64.sourceforge.net/">emacs-w64 | 64-Bit GNU Emacs for MS Windows with optimization</a>
    </li>
  </ul>

  <p>
    git リポジトリからつねに最新のバイナリを作成している.現在, version は 25.0??
  </p>
</div>

設定ファイル (.emacs) の場所を指定

.emacs.d を Cygwin と共有したい. init file の参照方法は以下のようだ.

1. If the environment variable HOME is set, use the directory it indicates.
2. If the registry entry HKCU\SOFTWARE\GNU\Emacs\HOME is set, use the directory it indicates.
3. If the registry entry HKLM\SOFTWARE\GNU\Emacs\HOME is set, use the directory it indicates. Not recommended, as it results in users sharing the same HOME directory.
4. If C:\.emacs exists, then use C:/. This is for backward compatibility, as previous versions defaulted to C:/ if HOME was not set.
5. Use the user’s AppData directory, usually a directory called Application Data under the user’s profile directory, the location of which varies according to Windows version and whether the computer is part of a domain.

HKCUというレジスタにパスを設定することにした. Win+R でファイル名を指定して実行を起動して, regedit と入力. レジストリエディタが起動するので, 対象のレジストリを作成. GNU と Emacs キーを作成. HOME の文字列値として以下を書いた.

[sourcecode language=”text” title=””]
C:\cygwin\home\TSUNEMICHI\dotfiles
[/sourcecode]

また, 環境変数から HOME を削除.

これで, cygwin の.emacs.d を参照するようになった.

Special Thanks

<div class="outline-text-3" id="text-3-1">
  <p>
    Official Site
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://www.gnu.org/software/emacs/manual/html_node/efaq-w32/index.html">GNU Emacs FAQ For MS Windows</a>
    </li>
  </ul>
</div>

13 Oct 2014, 10:00

VNC Server を利用して Linux-Windows or iPad でデュアルディスプレイをする方法

引越しをした

引越しをした.

今までは, ずっと東京都民・市民だったけれども, これからは神奈川県民だ. こころのどこかでずっと東京の神奈川に対する優位性と差別意識を抱いてきたけれども, それも本日で改めねば!

今まで利用していたデスクトップ PC だが, 4 年も利用していると起動が遅くて使いものにならなくなってきた.

そこで, この使えない デスクトップ PC を , 現在メインで利用しているノート PC のサブディスプレイとして 利用できないかどうか, 調べてみた.

Environment

<div class="outline-text-3" id="text-unnumbered-2">
  <ul class="org-ul">
    <li>
      Main PC: Panasonic Let&#8217;s Note, ArchLinux
    </li>
    <li>
      Sub PC: Fujitsu ESPRIMO, Windows 7
    </li>
  </ul>
</div>

インストール

以下の 2 つが必要なので, インストール.

  • tigervnc
  • x2vnc (AUR)

[sourcecode language=”sh” title=”” ]
% sudo pacman -S tigervnc
% yaourt -S x2vnc
[/sourcecode]

Vncserver の起動

<div class="outline-text-3" id="text-unnumbered-4">
  <p>
    vncserver の初回起動でパスワードが設定できるため, パスワード設定のために vncserver を起動.
  </p>

  <p>
    このパスワードは client からアクセスするときに必要.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221; ]<br /> % vncserver :1
  </p>

  <p>
    You will require a password to access your desktops.
  </p>

  <p>
    Password:<br /> Verify:
  </p>

  <p>
    New &#8216;localhost:1 (tsu-nera)&#8217; desktop is localhost:1
  </p>

  <p>
    Creating default startup script /home/tsu-nera/.vnc/xstartup<br /> Starting applications specified in /home/tsu-nera/.vnc/xstartup<br /> Log file is /home/tsu-nera/.vnc/localhost:1.log<br /> [/sourcecode]
  </p>

  <p>
    パスワード設定したら, 一旦 vncserver を停止する.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221; ]<br /> % vncserver -kill :1<br /> [/sourcecode]
  </p>

  <p>
    vncserver のスタートアップスクリプト ~/.vnc/xstartup を編集して, スタートアップで.xinitrc を利用するようにする.
  </p>

  <p>
    if [ -x /etc/X11/xinit/xinitrc ]; then の手前に以下のコードを追加.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221; ]<br /> if [ -f ~/.xinitrc ]; then<br /> exec sh ~/.xinitrc<br /> fi<br /> [/sourcecode]
  </p>

  <p>
    これで準備完了.以下のコマンドで起動.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221; ]<br /> vncserver :1 -alwaysshared<br /> [/sourcecode]
  </p>

  <p>
    vncserver は解像度や画面の大きさも設定できる. デフォルトでは, -depth 16 -geometry 1024&#215;768 が設定されている. -depth が解像度, -geometory が大きさ.
  </p>

  <ul class="org-ul">
    <li>
      <a href="http://www.obenri.com/_vnc/vnc_server2.html">http://www.obenri.com/_vnc/vnc_server2.html</a>
    </li>
  </ul>
</div>

x2vnc の起動

<div class="outline-text-3" id="text-unnumbered-5">
  <p>
    x2vnc は, ディスプレイ間でマウスやキーボード操作を共有するツール.
  </p>

  <p>
    以下のコマンドで起動する.
  </p>

  <p>
    [sourcecode language=&#8221;bash&#8221; title=&#8221;&#8221; ]<br /> % x2vnc -shared -east localhost:1
  </p>

  <p>
    x2vnc: VNC server supports protocol version 3.8 (viewer 3.3)<br /> Password:
  </p>

  <p>
    x2vnc: VNC authentication succeeded<br /> x2vnc: Desktop name &#8220;localhost:1 (tsu-nera)&#8221;<br /> x2vnc: Connected to VNC server, using protocol version 3.3<br /> x2vnc: VNC server default format:<br /> screen[0] pos=1603<br /> Xinerama detected, x2vnc will use screen 1.<br /> x2vnc: pointer multiplier: 1.719312<br /> [/sourcecode]
  </p>

  <p>
    Password は vncserver に設定したもの.
  </p>

  <p>
    表示させたい位置をオプションで指定できる. [-north] [-south] [-east] [-west]
  </p>
</div>

VNC Viewer から接続

ESPRIMO から接続

<div class="outline-text-3" id="text-unnumbered-7">
  <p>
    ESPRIMO に VNC Viewer を入れて, アクセスする.
  </p>

  <ul class="org-ul">
    <li>
      <a href="https://www.realvnc.com/download/viewer/">https://www.realvnc.com/download/viewer/</a>
    </li>
  </ul>

  <p>
    Address の入力欄には &#8220;(IP アドレス):1&#8243;というように:1 をつける.
  </p>

  <div class="figure">
    <p>
      <img src="http://futurismo.biz/wp-content/uploads/wpid-IMG_3851.jpg" alt="IMG_3851.jpg" />
    </p></p>
  </div>
</div>

iPad からの接続

<div class="outline-text-3" id="text-unnumbered-8">
  <p>
    クライアントを iPad にもできる. これで, 外出中もデュアルディスプレイ!
  </p>

  <p>
    iPad 用の VNC Client &#8220;VNC Viewer&#8221; を iPad にインストール.
  </p>

  <ul class="org-ul">
    <li>
      <p>
        <a href="https://itunes.apple.com/jp/app/vnc-viewer/id352019548?mt=8">iTunes の App Store で配信中の iPhone, iPod touch, iPad 用 VNC Viewer</a>
      </p>

      <p>
        AddressBook タブの右上にある + を押して, パソコンを登録する. Address の入力欄には &#8220;(IP アドレス):1&#8243;というように:1 をつける.
      </p>
    </li>
  </ul>

  <p>
    これで, iPad からも接続できた.
  </p>

  <div class="figure">
    <p>
      <img src="http://futurismo.biz/wp-content/uploads/wpid-IMG_3850.jpg" alt="IMG_3850.jpg" />
    </p></p>
  </div>
</div>

Special Thanks

<div class="outline-text-3" id="text-unnumbered-9">
  <ul class="org-ul">
    <li>
      <a href="http://d.hatena.ne.jp/kiwanami/20110514/1305388379">Linux で iPad をセカンドモニターにする &#8211; 技術日記@ kiwanami</a>
    </li>
    <li>
      <a href="https://wiki.archlinux.org/index.php/Vncserver_(%E6%97%A5%E6%9C%AC%E8%AA%9E)">Vncserver (日本語) &#8211; ArchWiki</a>
    </li>
    <li>
      <a href="http://pocke.hatenablog.com/entry/2014/01/18/155859">Android タブレットを Linux のディスプレイにしよう &#8211; pockestrap</a>
    </li>
    <li>
      <a href="http://nosada.hatenablog.com/entry/2012/09/11/144300">VNC を使って Android 端末をサブディスプレイにする &#8211; テクニカルプア</a>
    </li>
  </ul>
</div>

03 Oct 2014, 12:53

はじめて UML で設計を体験した

会社の話.

今週から, ソフト設計の工程に入った. UML のクラス図とコミュニケーション図を利用して, ソフトのアーキテクチャについて検討した.

実は, 仕事で UML を利用してクラス設計をするのは今週が社会人初なのだ!

Java による新規開発案件

今までの仕事は, C 言語での流用開発. switch 文に条件を追加していくだけの簡単なお仕事だったので, クラス設計やソフト構造の設計などまったく関わりがなかった.

しかし, 今回の仕事は Java の新規開発案件だ. そのため, はじめの設計で保守性の高いクラス構造を決める必要がある.

はじめての OO 設計

一応 UMTP L2 の資格を持っているし, デザインパターンについてもいろいろ調べたりしてきたけれども, 実践で利用したことがないということについて,とても歯がゆい気持ちでいた.

そのため, (ついに!) 仕事で クラス図をかけたことがとてもうれしいく感じた.

みんなでいろいろと意見を言い合ってソフト構造について議論するのだが, それがとても楽しい.

『このクラスの責務は重すぎるので, この責務は別のクラスに移譲するべきだ』

『このクラスたちは疎結合にするのがよい』

チームメンバで一人, とても OOP に詳しそうな人がいて, クラスの責務に関するコメントや, デザインパターンが言葉の端々に登場する. そういう開発に少し憧れていた.

『このクラスには状態が必要. ここはステートパターンで実装したほうがいい』

『ここには, ビジターパターンのような考えが利用できる』

TDD はやらない

ずっとやりたかった, Java での新規案件だけれども, ソフト構造を決めたらあとは黙々とつくっていくことになるのだろう.

もともと, Java をはじめた理由がケントベックの TDD の本を読むためだった ので, 実は TDD をしたいのだけれども, 今回の開発ではおそらく TDD はやらない.

今回の開発は, ネットワークの高速化をめざしいているため, 開発というよりも研究に近い. 動作するものを早くつくって性能を測ることが大事なので, テストは 2 の次なのだ. まずは性能を出すことが第一目標.

設計どおりにつくって高い品質を確保できたとしても, 性能がでなければなんの意味もない.まずは, 動かしてチューニングしたい.

そしてデスマーチへ

しかし, このプロジェクトは今の時点でデスマーチな匂いがとてもする…

か弱い下請け仕事なので, 強いられた工程を死守しないといけないのだが, 結構乱暴な工程が引かれている… 今の時点で正月がない気がするのだが. 思ったように性能がでないときに, 真の地獄が待っている…

楽しさと辛さが紙一重なのだが, なんとか頑張るつもり.

01 Oct 2014, 12:06

Milkode を Windows に導入

Install

事前に Windows に Ruby と DevKit をいれておく.

gem で取得.

[sourcecode language=”text” title=”” ]
gem install milkode
[/sourcecode]

eventmachine のインストールでコケた.

以下のページを参考にして, git リポジトリから eventmachine を取得した.

[sourcecode language=”text” title=”” ]
gem install specific_install
gem specific_install -l ‘git://github.com/u338steven/eventmachine.git’
[/sourcecode]

再度, milkode をインストールして完了. それにしても, 依存関係が多すぎる…

つかってみる

デフォルト設定をまずは設定.

[sourcecode language=”text” title=”” ]
$ milk init –default
[/sourcecode]

検索対象のリポジトリを追加する.

[sourcecode language=”text” title=”” ]
$ milk add .
[/sourcecode]

Web 画面を起動. port はデフォルトでは 9292 なので, 変更した.

[sourcecode language=”text” title=”” ]
$ milk web -p 9293
[/sourcecode]

すると, ブラウザが立ち上がってソースコードが閲覧できる. 便利!

Environment

<div class="outline-text-3" id="text-2-1">
  <ul class="org-ul">
    <li>
      Windows 8 64bit
    </li>
  </ul>
</div>

Special Thanks

<div class="outline-text-3" id="text-2-2">
  <ul class="org-ul">
    <li>
      <a href="http://tori932.dip.jp/Program/%E6%9C%80%E6%96%B0%E3%81%AEMilkode(1.8.0)%E3%82%92Windows%E3%81%A7%E8%A9%A6%E3%81%99">最新の Milkode (1.8.0) を Windows で試す | tori&#8217;s home</a>
    </li>
  </ul>
</div>