今回の解答は、「クライアントとサーバ間の送受信データの構造体が異なる」です。
本問題では、音楽プレーヤーのクライアントとサーバがTCPで通信しています。両者のやりとりのデータは、ヘッダファイルに記載しているのですが、両者で順番が異なっています。
図2は、クライアントとサーバの送受信用の構造体をコメント抜きで抜粋したものです。見れば分かる通り、構造体メンバのidとpasswordの並び順が異なっています。そのため、両者で異なるデータを上書きしていました。結果、モードは正しく表示でき、残りは不正データとなりました。つまり、A君とB君の最大の失敗は、共通のヘッダファイルを使わず、別々に定義したことにあります。
「超初心者の単純なバグ」と思った方もいるかと思いますが、この類いのバグはたまに起こります。例えば、データの転記ミス、エンディアンや構造体のアライメントの違いなどから、正しいデータを送っているつもりでも意図している値を送受信できない場合があります。下記に詳細を示します。
データの転記ミスですが、送受信するデータは何らからの開発ドキュメントに書いてあります。プログラマーがその記述を間違えて記載すると、想定外の値が現れます。
エンディアンとは、バイト列の並び順のことです。本問題では、Intel系CPUですから、ビックエンディアンを使っています。場合によっては、相手はビックエンディアンでもう片方がリトルエンディアンの場合があるので注意が必要です。両者が違う場合は、値が反転して現れます。
構造体のアライメントとは、コンパイラが一定の間隔でデータを整列することです。例えば、構造体のメンバ変数に「char型変数」と「int型変数」の2つある状態でサイズを取得することを考えます。char型のサイズを1バイト、int型のサイズを4バイトとすると、「1バイト+4バイト=5バイト」となるように思いますが、実際は、「1バイト+3バイト+4バイト=8バイト」と3バイト詰め物をいれることがあります。何バイトの詰め物を入れるかは、コンパイラに依存しますので、結果として送受信側のデータサイズが異なることになります。
今回の自己採点シートを以下に示します。
問題 | 内容 | 配点(点) |
---|---|---|
ネットワーク型音楽プレーヤープログラム | 問題を一通り読んだ | 20 |
クライアント側プログラムを一通り読んだ | 20 | |
サーバ側プログラムを一通り読んだ | 20 | |
バグの原因が、構造体の順番が異なっていることを見つけた | 40 | |
その他のバグを見つけた | +5 | |
リスト4 自己採点シート |
近年のIT技術の発達により、複数の機器が相互に連動して動くソフトウェアが増えてきました。今回は、その一例としてTCPを題材とした問題を出題しました。たかだか構造体の順番の話でしたが、何らかの原因で意図したデータを送受信できないことがあります。その場合は、冷静に送受信側にログを入れておき、正しいデータが送れているかもう一度確認すると良いでしょう。また、両者の機器の違いを明確にしておくとバグの未然防止につながります。
余談ですが、今回のプログラムには、エラー処理はほとんど記述していませんが、通信系ソフトでは通信異常などのエラー処理も大切です。このプログラムを題材としてその他のバグを見つけると面白いと思います。
「TCP/IPソケットプログラミング C言語編」(小高知宏(訳)、2003年、オーム社)
「Linuxシステムコール基本リファレンス──OSを知る突破口(WEB+DB PRESS plus)」(山森丈範、2018年、技術評論)
東海大学 大学院 組込み技術研究科 非常勤講師(工学博士)
Copyright © ITmedia, Inc. All Rights Reserved.