« 2014年8月 | トップページ | 2014年10月 »

2014年9月

2014年9月30日 (火)

「ブリュンヒルデ零式改」をVS2013 for Desktopで作ってみます その2

DirectXの設定はなんにもしていませんが、とりあえずビルドしてみます。エラーが出たらそこで考えましょう。

Error

エラーで止まりました。

関数strcpy()は危ないので、strcpy_s()を使え!

とのことです。やっぱりSDLのチェックに引っ掛かったようですね。ソースファイルを変更しないというポリシーで一応いきたいので、ここではSDLチェックをOFFにしましょう。

ソリューションエクスプローラでプロジェクト(zerosikikai)を選択して、さらに左クリックして「プロパティ」を選択します。

「構成プロパティ」→「C/C++」→「全般」と進んで、「SDL チェック」の項目を「はい」から「いいえ」に変更します。


20140930_134752


20140930_134803

プロジェクトを作る時にチェックを外しておけばよかったんですね…

「適用」を押して、変更を終了します。

さて、再びビルドすると…あれ、正常にビルドが終わりました。Releaseビルドは…あれ、正常にビルドは終わりました。

以下のメッセージは出てますが、コンパイル自体は正常終了してます。

d:\src\zerosikikai\zeroshikikai.cpp(925): warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\program files (x86)\microsoft visual studio 12.0\vc\include\string.h(112) : 'strcpy' の宣言を確認してください。

strcpy()は安全ではないですが、まぁ検証目的なので…とりあえずよしとします。

DirectXの設定は特に要らなかったようです。少し拍子抜けですがヽ(´▽`)/

ちなみにDebugビルド版は47KBのサイズでした。

「Debugビルド版(変わりませんが…)」(◎´∀`)ノ

20140930_135813

(追記)

ビルドできましたが、接続直後に停止します…なぜだろう。

20140930_142520


20140930_142514

デバッグ実行すると…うーん。

20140930_143607


「ブリュンヒルデ零式改」をVS2013 for Desktopで作ってみます

いろいろと動作確認するために、「ブリュンヒルデ零式改」をVisual Studio 2013 for Desktop(以下VS2013) で作ってみます。

Direct Soundを使っているので、DirectXのインストールが必要です。"dsound.h"というヘッダーファイルをエクスプローラーで探しますと、

20140930_112648

20140930_112808

な感じで見つかりました。"dsound.h"は

C:\Program Files (x86)\Windows Kits\8.1\Include\um

にあるみたいです。

とりあえずDirectXの環境はありそうなので、とりあえずVS2013でプロジェクトを作ってみます。

VS2013を起動して、「ファイル」メニューから「新しいプロジェクト」を選択しました。

テンプレートから「Visual C++」を選択して、「Win32」→「Win32プロジェクト」選択します。

「名前」と「場所」を適当に設定します。私は"zerosikikai"と"D:\src\zerosikikai\"にしました。ディレクトリは予め作って"zerosikikai.cpp"をコピーしておいたので、ここでは作成しません。

「OK」を押して次へ進むと「完了」が押せるようになりますが、ここでは「次へ」を押しました。

「アプリケーションの種類」が「Windowsアプリケーション」になっていることを確認して、「追加のオプション」の所の「空のプロジェクト」にチェックを入れました。サンプルソースはコピーしてあるのでテンプレートのソースは必要ないですね。「Security Development Lifecycle(SDL)チェック」ってやつは、よくわかりませんが、恐らくセキュリティ上問題になりそうなコードを指摘してくれたりするのかもしれませんね…、とりあえず初期設定のままにします。

「完了」を押して、プロジェクトを作成します。

"D:\src\zerosikikai\"の下にzerosikikaiというフォルダーが出来ました(^_^;でもサンプルソースは"D:\src\zerosikikai\zerosikikai.cpp"です。ちょっと予想とは違いますがソースコードがプロジェクトファイルに紛れると面倒なので、このままいきます。

出来上がったプロジェクトにはソースファイルが登録されていないので、まず"zerosikikai.cpp"を新規登録しましょう。右の方にある「ソリューションエクスプローラ」で、"zerosikikai"の下にある「ソースファイル」を選択して、左クリックするとメニューが現れますので、「追加」を選択します。

続けて「既存の項目」を選びますとファイル選択ダイアログが表示されます。
で、1つ上のフォルダにある"zerosikikai.cpp"を選択します。

これでサンプルソースが追加されました。ソリューションエクスプローラで"zerosikikai.cpp"をダブルクリックすれば、ソースが表示されるはずです。

長いので、とりあえずここで区切ります。

フォルダ内容はこんな感じ。

20140930_120921


20140930_120928


2014年9月22日 (月)

キーボード、マウス情報のバッファリングを確認しました

キーボードとマウスの動作情報をそれぞれのバッファに格納するところまで確認しました。

$ ./release/qtbrynhildr.exe
[MouseBuffer] : POS : value = (51,799) : size() = 0
[MouseBuffer] : POS : value = (51,798) : size() = 1
[MouseBuffer] : POS : value = (51,797) : size() = 2
[MouseBuffer] : LEFT_BUTTON : value = 1 : size() = 3
[MouseBuffer] : LEFT_BUTTON : value = 2 : size() = 4
[MouseBuffer] : RIGHT_BUTTON : value = 1 : size() = 5
[MouseBuffer] : RIGHT_BUTTON : value = 2 : size() = 6
[MouseBuffer] : LEFT_BUTTON : value = 1 : size() = 7
[MouseBuffer] : LEFT_BUTTON : value = 2 : size() = 8
[MouseBuffer] : LEFT_BUTTON : value = 3 : size() = 9
[MouseBuffer] : LEFT_BUTTON : value = 2 : size() = 10
[MouseBuffer] : WHEEL : value = 15 : size() = 11
[MouseBuffer] : WHEEL : value = 15 : size() = 12
[MouseBuffer] : WHEEL : value = 15 : size() = 13
[MouseBuffer] : WHEEL : value = 15 : size() = 14
[MouseBuffer] : WHEEL : value = -15 : size() = 15
[MouseBuffer] : WHEEL : value = 15 : size() = 16
[MouseBuffer] : WHEEL : value = -15 : size() = 17
[KeyBuffer] : KEYDOWN : VK_Code = M: size() = 0
[KeyBuffer] : KEYUP : VK_Code = M: size() = 1
[KeyBuffer] : KEYDOWN : VK_Code = C: size() = 2
[KeyBuffer] : KEYUP : VK_Code = C: size() = 3
[KeyBuffer] : KEYDOWN : VK_Code = Z: size() = 4
[KeyBuffer] : KEYUP : VK_Code = Z: size() = 5

"size()"はそれぞれのバッファに残っている情報の数を表示しています。まだBrynhildrサーバさんに送信していないので今は溜まる一方です。このままではバッファが溢れてしまうので長くは動作できません。

GUIを処理するスレッドで行うことはここまでです。

キーボード、マウスの動作情報を送るのはGUIとは違う通信用スレッドになります。排他制御しながら、送った情報はバッファから速やかに削除しなければなりません。

2014年9月21日 (日)

とりあえずマウスイベントを確認する

暫定でキーボードの情報、マウスの情報をバッファリングするクラスを作ったのですが、最終的に通信で送信する入力デバイスの情報はこれからTrial and Errorで調整する必要があります…

Qtでイベントが取得できないでいるキーも気になるのですが、まず簡単そうなマウスイベントを確認しました。

ボタンのクリック、リリース、ホイールの正転、逆転は簡単に取得できるのですが、マウスが移動する度に起こるはずのmouseMoveEventが実行されません。マウス移動情報をBrynhildrサーバさんに送らなければならないので、これでは困ります。

Qt Assistant で QWidget の項目を眺めると、メソッド「mouseMoveEvent()」の説明に「setMouseTracking()」へのリンクがありました。mouse tracking mode というのを true に設定しないとこのイベントは起きないそうです。

MainWindowのコンストラクタに setMouseTracking(true) を追加したら、マウスを移動する度にイベントが発生するようになりました。マウスの移動情報が必要ないアプリケーションなら、トラッキングする必要はないので初期設定では false になっているようですね。

[Debug Print]

$ ./release/qtbrynhildr.exe
[MainWindow] mouseMoveEvent: QPoint(45,7)
[MainWindow] mouseMoveEvent: QPoint(45,16)
[MainWindow] mouseMoveEvent: QPoint(45,26)
[MainWindow] mouseMoveEvent: QPoint(45,34)
[MainWindow] mouseMoveEvent: QPoint(45,40)
[MainWindow] wheelEvent: 15 (ticks = 1 )
[MainWindow] wheelEvent: 15 (ticks = 1 )
[MainWindow] wheelEvent: -15 (ticks = -1 )
[MainWindow] wheelEvent: -15 (ticks = -1 )
[MainWindow] wheelEvent: 15 (ticks = 1 )
[MainWindow] wheelEvent: -15 (ticks = -1 )
[MainWindow] wheelEvent: -15 (ticks = -1 )
[MainWindow] wheelEvent: 15 (ticks = 1 )
[MainWindow] wheelEvent: -15 (ticks = -1 )
[MainWindow] wheelEvent: -15 (ticks = -1 )
[MainWindow] mouseMoveEvent: QPoint(48,79)
[MainWindow] mouseMoveEvent: QPoint(49,76)
[MainWindow] mouseMoveEvent: QPoint(50,74)
[MainWindow] mouseMoveEvent: QPoint(51,73)
[MainWindow] mouseMoveEvent: QPoint(51,71)
[MainWindow] mouseMoveEvent: QPoint(52,70)
[MainWindow] mousePressEvent: Left Button : QPoint(52,70)
[MainWindow] mouseReleaseEvent: Left Button : QPoint(52,70)
[MainWindow] mousePressEvent: Right Button : QPoint(52,70)
[MainWindow] mouseReleaseEvent: Right Button : QPoint(52,70)
[MainWindow] mouseMoveEvent: QPoint(52,71)
[MainWindow] "JP" : Press : VK_Code = 44
[MainWindow] "JP" : Release : VK_Code = 44
[MainWindow] "JP" : Press : VK_Code = 51
[MainWindow] "JP" : Release : VK_Code = 51
[MainWindow] "JP" : Press : VK_Code = 44
[MainWindow] "JP" : Release : VK_Code = 44
[MainWindow] "JP" : Press : VK_Code = 20
[MainWindow] "JP" : Release : VK_Code = 20
[MainWindow] "JP" : Press : VK_Code = 20
[MainWindow] "JP" : Release : VK_Code = 20
[MainWindow] "JP" : Press : VK_Code = 51
[MainWindow] "JP" : Release : VK_Code = 51
[MainWindow] mouseMoveEvent: QPoint(52,72)
[MainWindow] mouseMoveEvent: QPoint(52,71)
[MainWindow] mouseMoveEvent: QPoint(52,70)
[MainWindow] mouseMoveEvent: QPoint(51,69)
[MainWindow] mouseMoveEvent: QPoint(50,67)

(追記)

ダブルクリックイベント(mouseDooubleClickEvent())もハンドリングしないといけなさそうです。
inputMEthodEvent()も調査しないと。

2014年9月17日 (水)

キーボード、マウス情報をバッファリングする

キーボードやマウスの動作の情報(イベント)はQWidgetを継承したMainWindowというクラスで処理しています。
キーが押されたり、マウスのボタンをクリックする度に特定の関数が呼ばれる仕組みになっていて、どのキーが押されたかとかどのマウスボタンが押されたかなどの情報は関数の引数として渡ってきます。

これらの情報を時系列で順番にBrynhildrサーバーさんに送ります。ただ、これらの情報を貯めておくところはMainWindowクラスの中なのですが、Brynhildrサーバさんと通信するのはMainWindowと同じスレッドではありません。

このため、マルチスレッドでの生産者と消費者の問題が生じます。「入門Qt4プログラミング」の第18章マルチスレッド に簡単な説明がありますね。まぁ、簡単にいうとキーボードを押したはずなのに、押せなかったり、マウスの動きが変だったりするわけですね、多分。

で、これを正確に処理するために、データを書き込んでいる途中で読み出したり、読みだしている途中で上書きしたりするようなことを回避する仕組みを入れるないといけません。

Qtではそのための仕組みがいくつか実装されていて、お手軽に使うことができるようです。ただし、基本的な概念を知っておく必要はあると思います。

その仕組みを入れる前にまずキーボード/マウスの情報を貯めておくためのクラスを作ろうと思います。PCMデータの送受信でも使ったリングバッファというものを使います。

とりあえずUS Keyboard対応の準備をする

日本語のキーボードの暫定対応が終わったので、USキーボードの準備をしました。正確には対応するソースファイルを準備しただけです(中身は日本語キーボードの処理のまま)。

これに対応して接続ダイアログにキーボードタイプを選択する項目を追加しました。Qt Designerで追加するだけなので楽チンです。追加した項目名の翻訳も必要でした。

20140917_151457

"Japanese"と"US"しか選べません。(必要な人には追加してもらいましょう)

今はcygwinコンソールに以下のようなデバッグプリントが表示されます。この情報を貯めておいてBrynhildrサーバさんに少しずつ送ればいいようです。

[MainWindow:US] VK_Code: "VK_A"
[MainWindow:US] VK_Code: "VK_B"
[MainWindow:US] VK_Code: "VK_A"
[MainWindow:US] VK_Code: "VK_B"
[MainWindow:US] VK_Code: "VK_1"
[MainWindow:US] VK_Code: "VK_2"
[MainWindow:US] VK_Code: "VK_3"
[MainWindow:US] VK_Code: "VK_4"
[MainWindow:US] VK_Code: "VK_5"
[MainWindow:US] VK_Code: "VK_OEM_4"
[MainWindow:US] VK_Code: "VK_OEM_6"

これを表示しているのはメインスレッドなので、操作情報を送るControl Threadと共有バッファを設けることになります。

あと必要な対応は、全角/半角、Windows Key、変換、無変換、Kana/Hiraの各キーイベントが通常だと取得できないという状況を調査することです。マウスイベントのデバッグプリントもやらないと。

(追記)
マウスイベントの情報を表示させてみました。wheel eventは1 tickごとに送られるようです。

[MainWindow] mousePressEvent: Left Button
[MainWindow] mouseReleaseEvent: Left Button
[MainWindow] mousePressEvent: Right Button
[MainWindow] mouseReleaseEvent: Right Button
[MainWindow] wheelEvent: 15 (tick = 1 )
[MainWindow] wheelEvent: 15 (tick = 1 )
[MainWindow] wheelEvent: -15 (tick = -1 )
[MainWindow] wheelEvent: -15 (tick = -1 )
[MainWindow] wheelEvent: -15 (tick = -1 )

Qt 5.3.2がリリースされてました

昨晩は重くてダウンロードを断念しましたが、今朝は軽くなってましたのでダウンロードできました。
マイナーバージョンアップだと思いますが、詳細はまだ調べていません…

以下のブログを読まないと…Qt Creatorが新しくなった…のかな。(今は使ってないけど)

http://blog.qt.digia.com/blog/2014/09/16/qt-5-3-2-released-with-qt-creator-3-2-1/?utm_source=rssutm_medium=rssutm_campaign=qt-5-3-2-released-with-qt-creator-3-2-1

あと開発者のためのサイトが宣伝されていますが、よく分かりません。

http://www.qt.io/developers/

2014年9月16日 (火)

時々気分転換を…

#カテゴリー完全無視ですな…

内容が内容なだけに、基本、検索から立ち寄って直帰な方が多いのですが(まだ何もリリースできていない時点で当たり前ですね…)、2つのコメントと1通のメールを頂きました。

いずれも海外の方なので、少しびっくりですね。

"Brynhildr Android"とか"Brynhidr Linux"とかで検索するとなんとなく表示されるようですが、

"なんだ、まだ出来てないじゃん"

となりますね。

最新バージョンのBrynhildrのパブリックモードレベルの機能を実装するつもりですが、パブリックモード故にファイル転送とクリップボードはサポートできないんですけどね。

私自身ファイル転送とクリップボードを使うことがないので問題なしなんですが、パブリックモードの制限なので私にはどうにもできないです。

メールの問い合わせ内容ですが…

(Q) Angstrom Linuxで動きますか?
(A) Qt5があれば動くんじゃないでしょうか?(Qtの重さに耐えられるのかは分かりません)

(Q) USキーボードなんでお願いします。
(A) 持ってないですけどね…どこかから入手しないといけませんねぇ。

Beagle Bone Blackは入荷待ちで予定立たず、USキーボードはどうしようかな…

#タイトルも無視だな…

2014年9月11日 (木)

JPEG イメージが壊れています…その3

原因が…分かったような気がします。

書くのも恥ずかしいのですが…

デバッグプリントの出しすぎ…です。

cout << "xxxxx" << endl << flush;

と、ばんばんデバッグプリントを、ご丁寧に一行毎にflushしながら出力しておりました…

標準出力への出力+バッファフラッシュには結構時間がかかりますよね…

そのおかげでネットワーク受信が間に合わなかった模様です。

いま出力しているデバッグプリントはこんな感じ。

[ControlThread] start thread...start run()
[ControlThread] connectToServer(): connected
[ControlThread] connectedToServer() : connected...
[GraphicsThread] start thread...start run()
[GraphicsThread] connectToServer(): connected
[GraphicsThread] connectedToServer() : connected...
[SoundThread] start thread...start run()
[SoundThread] connectToServer(): connected
[SoundThread] connectedToServer() : connected...
[ControlThread] stop thread...exit run()
[GraphicsThread] stop thread...exit run()
[SoundThread] stop thread...exit run()
[ControlThread] disconnectedToServer() : disconnected...
[GraphicsThread] disconnectedToServer() : disconnected...
[SoundThread] disconnectedToServer() : disconnected...

JPEG イメージが壊れています…その2

JPEGイメージが壊れていることはわかったのですが、どんな風に壊れているんでしょう。

これまでデバッグ用にJPEGファイルのデータを1枚のみ保存するようにしていました。これではどんどん上書きされてしまってデータが残らないので検証のしようがありません。これを改善するため、ファイル名を連番にしてすべてのJPEGファイルデータを残すように変更しました。

jpgというディレクトリの下に連番で"graphics_output_000000.jpg"という感じで起動時から受信したすべてのデータを残すようにしました。(jpgというディレクトリは決め打ちなんですが…)これで後でデータを検証できます。

起動して、実行してみました。

[壊れたJPEG 1]

20140911_143245

かろうじてJPEGのヘッダーはありますが、途中でおかしなデータになってるようですね。

[壊れたJPEG 2]

20140911_143314

JPEGヘッダもおかしいので表示できません。もう受け取っているデータ自体がおかしいですね。バイナリエディタで見てもヘッダー部がめちゃくちゃです。

どうやらloadFromData()に渡しているデータ自体がすでに壊れているようですが、どのタイミングで壊れているのでしょうか…Threadのローカルバッファに格納した時点で壊れているようですね…

2014年9月10日 (水)

「ブリュンヒルデ零式改。」

「ブリュンヒルデ零式改。」公開だそうです。

今回は実際に試せる実行ファイルも公開されました。16KBのサイズです、スゴイですね…

ブリュンヒルデ零式改。

sound_capture が"1"(CoreAudio)固定なのでXPがサーバの場合は音がでないですかね?
サーバがVista以降なら大丈夫でしょうか?

XPサーバ、8.1 updateクライアントの組み合わせでは一瞬繋がった後落ちてしまいました…orz

#「ブリュンヒルデ零式Z」がいつか出るのでしょうか(o^-^o)

ブログのコメントを見るとAndroid版を作ろうとしている方もいるみたいですよ。 > これを読んだ方ヽ(´▽`)/

JPEG イメージが壊れています…

Windows/Ubuntuで確認していますが、JPEG Imageが壊れている時が時々(Ubuntuでは結構な頻度で)あります。

怪しげなデスクトップ画面が再現されます(;ω;)

Corrupt JPEG data: premature end of data segment

とか

Corrupt JPEG data: 872 extraneous bytes before marker 0xd9

というようなメッセージがコンソールに出ます。いろいろ調べてみたら、メッセージ自体はlibjpeg(プラグインqjpeglib)さんが出しているっぽいです。

QPixmap::loadFromData()を使ってバッファからロードして、ちゃんとロードできたらtrue、失敗したらfalseを返すような説明があるのですが、下位関数で"Corrupt"のメッセージが出ているにも関わらず、trueを返しているようです。

stackoverflowなどに質問している人もいますが、結局のところ正しくtrue/flaseは返っていないということらしいです。

http://www.qtcentre.org/threads/19917-Loading-corrupt-jpeg-images-with-QImage

さてどうしたものですかねぇ…きちんと調べといた方がいいですよね…

もしloadFromData()が正しくtrue/falseを返してくれるなら、データがおかしい時(falseの時)だけ表示しないという手もあるのですが…(◎´∀`)ノ

2014年9月 6日 (土)

進捗記録 2014.9.6

マルチスレッドでの実装開始から3週間かかってやっとデスクトップ画面を表示できるまで再実装できたので進捗記録します。

次にサウンドを実装しようかと思いましたが、操作できるのをみたいので(笑)マウスとキーボードを実装しましょう。
基本的にはQtのeventをマウスの動き(右クリック、左クリック、それぞれのダブルクリック、ホイールの回転角度)としてBrynhildrサーバに伝えます。

キーボードはQtから取得できるキー情報からWindowsの仮想キーコードに変換して、あたかもWindowsからのメッセージのようになんとなく伝えればよさそうです。サーバ側で使っているキーボードタイプが分かれば一番いいのですが、今のところサーバから情報は頂けないので、接続ダイアログに「キーボード(Key board type)選択」の項目を追加しなくてはなりませんね。とりあえず私の使っているキーボードで実装しますが(*^-^)

ホイールの回転角度はQtの場合回転角度の8倍の数値が取得できるようなので、これを少し調整してヘッダーに格納して送ればよさそうです。マウスの位置はウィンドウの縦、横サイズから算出して伝えます。

これらの情報をヘッダーに含めてサーバに送ります。一度の送信で基本的に一回の情報を伝えるので、入力デバイスの操作情報はバッファリングしておく必要があります。やっぱり、再度リングバッファの登場ですかね…

キャプチャ画面を撮りました。

Qt Brynhildr (仮称) [前面]とWindows XP on VMware Workstation [後面]です。

画面描画中に、GraphicsThreadがバッファに書き込んでしまうことがあるようなので、lockしないといけなさそう…

20140906_092510

Brynhildrサーバのバージョンは1.0.4です。

2014年9月 4日 (木)

オープンソースソフトウェア(OSS)について考える

基本的な機能が実装できたら、ソースコードを公開するかなぁ、となんとなく考えていました。

GPLv2をベースに、と考えていたのですがいろいろと考えるべきことがありそうです。

ライセンスについてまとめている方がいらっしゃいました。

「オープンソース・ライセンスの談話室」

電子書籍化されているそうなので、少し読んでみますかねぇ。

私一人の能力などたかが知れているので、できればみなさまのお力をお借りしたいですね。
#とここでつぶやいてもどうしようもないのですが( ^ω^ )

今年の目標(というか夢?)は…

1) キーボード、マウスサポート (Windows/Ubuntu)
2) Windows/Ubuntu版のリリース
3) タッチパネルサポート (Android)
4) Android版の動作確認

くらいで。

#あと3ヶ月で今年も終わりですねぇ…(^-^;

なんか、このブログの趣旨がよくわからなくなってきました。

「ブリュンヒルデ零式」の公開、だそうです

Brynhildr のクライアントのサンプル ソースコード(sample source code)が公開されました。前回に引き続きpublilc domainだそうです。

「ブリュンヒルデ零式」

という名前で、Windows向けクライアントのサンプルソースとなっています。

実際にデスクトップを操作できるバージョンなので、Windows clientにチャレンジする方が出てくるのではないでしょうか。楽しみですね。

「ブリュンヒルデ零式。」

# WSACleanup()は入ってなかった…

# タイトルが「週刊ブリュンヒルデ」ではなかったですね… (*^-^)

[ご参考]
「週刊ブリュンヒルデ創刊号。」

(追記)
WSACleanup()はWinSockを使い終わったら実行するのが基本と入門書にはありますが、少し問題があったことが以前あったそうでたまたま入っていないそうです、難しいですね。

2014年9月 1日 (月)

通信スレッドの構造が全然ダメでした…

最初の制御用通信の接続はするもののそこから全然進みません。

connected()のシグナルが届いた後最初のヘッダーを送出しますが、Brynhildrサーバさんから返事が届きません。

仕方がないので、サーバを起動しているVMware Workstation上のXP ProにWinsharkをインストールしました。
ネットワークパケットをキャプチャしてみます。XPでは少し古いバージョン(v1.10)を入れる必要があるそうです。

ポートとして55500を指定しているので、フィルタの所に"tcp.port==55500"を指定すれば、Brynhildr用のパケットがキャプチャできます。"Capture"メニューから"Start"を選んでキャプチャを開始します。

サーバへ接続してみますと…「ん、最初のコネクション確立用のパケットしか出ていない」みたいです。
接続を切断すると接続を切るための[FIN]パケットのやりとりしか出ていません。

ヘッダー(256バイト)を送出しているはずなんですが、それらしきパケットはありません。

Qtの質問サイトを探してみると少し気になる記述がありました。

QTcpSocketに write() した場合に flush() すると直ちにデータを送るよ、という指摘でした。

これまで特にflush() した記憶はないのですがうまく行っていたのでこれまで記述していませんでした。

早速write() の後に flush() するように記述して再実行しました。Winsharkの結果を見ると、

「お、256バイトのデータが送られている…」

flush() をしなければならないのか…、しかしシングルスレッドで今までうまく行っていたので納得がいきません。

確認のためQt Assistantを開き調べることにしました。QTcpSocketのスーパクラスであるQAbstractSocketのところに flush() の説明がありました。

「flush() すれば直ぐにwrite bufferをflushするよ、でも大体は必要なんだけどね…」 え?

「event loopで自動的に処理されるから…」 なんですと?

QThreadを継承しrun() の中に処理を記述すればいいよと入門書には書いてあったのですが、
その中でexec() を呼ばないとevent loopが開始されないのだそうです…うぇ…
で、そのイベントループでソケットのバッファがフラッシュされるのだそうです。

[参考]
http://www.qtcentre.org/archive/index.php/t-29932.html

run() の中で500msスリープしながら永久ループで構成していました。

単純にすると以下の様な構造です。

void run()
{
connectToServer();

while(true){

if (stopped)
break;

msleep(500);
}

disconnectToServer();
}

以下のような構造に変更しました。

void run()
{
connectToServer()

exec(); // event loop start

disconnectToServer()
}

QThread::exit()を呼び出せば、イベントループexec() は終了し、サーバーの切断処理を行い、スレッドが終了します。
というわけで、3つの通信スレッドを起動して、Brynhildrサーバーさんと通信し、データが転送できるところまで確認できたのですが…

« 2014年8月 | トップページ | 2014年10月 »