C言語関係掲示板

過去ログ

No.339.伝送制御コードについて

[戻る] [ホームページ]
No.2153

伝送制御コード(通信の基礎)について
投稿者---ゆき(2002/07/23 10:44:20)


Cの初心者です。よろしくお願いしますm(__)m

現在、ベーシック手順という伝送制御を行おうとしています。
パスワード認証を行い、<ENQ>を送って<ACK>が返ってきたとこ
までは良かったのですが、テキストを送ろうとしても反応してくれません。
*******************************************
<DLE><STX><01>・(テキスト)<DLE><ETX>B・
*******************************************
これが正解のらしいのですが、「B・」が何なのか分かりません。
<01>は第1ブロックでして、直後の「・」は「0xff」という16進数を
入れているようです。<ETX>の後に決まった文字を
付けなくてはいけないのでしょうか?
改行や復帰も試してみましたが認証してくれません。
サーバー側の仕様なのかも知れませんが、Cがイマイチ分からないので
困っています。どなたかお助け願いますm(__)m

一応、サーバー側のその通信を行ってると思われる部分の
ソースを以下に書いておきます。
*************************************************
rs_putc( SC_DLE );
rs_putc( SC_STX );
ch = Snd.bno & 0xff;
if( ch == SC_DLE ){ rs_putc( SC_DLE ); }
rs_putc((unsigned char)ch );
ch = ~ch;
if( ch == SC_DLE ){ rs_putc( SC_DLE ); }
rs_putc((unsigned char)ch );
crc16_begin();
Snd.cp = Snd.rp;
for( i = 0;( i < 256 )&&( Snd.cp < Snd.wp );i++ ){
ch = Snd.buf[Snd.cp];
if( ch == SC_DLE ){
if( i == 255 ){ break; }
rs_putc( SC_DLE ); i++;
}
crc16_calc((byte)ch);
rs_putc((unsigned char)ch ); Snd.cp++;
}
rs_putc( SC_DLE );
rs_putc( SC_ETX );
crc = crc16_get();
rs_putc((unsigned char)(( crc >> 8 ) & 0xff));
rs_putc((unsigned char)(crc & 0xff));
*************************************************


No.2155

Re:伝送制御コード(通信の基礎)について
投稿者---PSB(2002/07/23 13:18:11)


「ベーシック手順という伝送制御」というのは私にもさっぱりなのですが、Cのコード
部分だけ解析してみましょう。順に

(1)DLE送信
(2)STX送信
(3)bno送信
(4)bnoの補数送信
(5)テキスト送信
(6)テキストの16ビットCRC(?)の上位8ビット送信
(7)テキストの16ビットCRC(?)の下位8ビット送信

(?)となっているのはcrc16_get()という関数から推測したものです。
多分テキストのCRCを後ろにくっつけて送信するという仕様なんじゃないでしょうか?


No.2158

Re:伝送制御コード(通信の基礎)について
投稿者---ともじ(2002/07/23 15:22:52)


こんにちは。

>「ベーシック手順という伝送制御」というのは私にもさっぱりなのですが、Cのコード
> 部分だけ解析してみましょう。
> 多分テキストのCRCを後ろにくっつけて送信するという仕様なんじゃないでしょうか?

手持ちのテキストによると、ベーシック手順のメッセージフォーマットは、
 <STX><データ><ETBまたはETX><BCC>
ですので、BCC(Block Check Character;誤り制御文字)にCRCを使って
いるものと思われます。

> <DLE><STX><01>・(テキスト)<DLE><ETX>B・
> これが正解のらしいのですが、「B・」が何なのか分かりません。

CRC演算については、
http://www.infomicom.mesc.co.jp/M16C/apl/crc/crcj.htm
が詳しいようですので、参考にしていただくとして、
具体的にはサーバ側のプログラムでテキスト部を送信しながら
CRCの算出も行っているようですので、そのまま流用し、
CRCを付加して送るようにすれば、受信を受け付けてもらえると
思います。


No.2161

Re:伝送制御コード(通信の基礎)について
投稿者---ゆき(2002/07/23 17:24:31)


PSBさん、ともじさん、ご返答ありがとうございます。

 通信をするにあたって、CRC制御というものが存在する
ことさえ知りませんでした。ありがとうございます。
ご提示されていたCRC演算のページを読んでも、
難し過ぎてできるか分かりませんでしたが、
もっと調べてやってみようと思っています。

PSBさんが指摘してくれましたcrc16_get()という関数が
明確に見つけられなかったのですが、それらしき場所の
ソースは以下のようになっています。

********************************************************
static unsigned int crc16_t[256];
static unsigned int crc;

void crc16_init( void )
{
static int far i;
static int far j;

for( i = 0 ; i < 256 ; ++ i )
{
crc = i;
for( j = 0 ; j < 8 ; ++ j )
{
if( crc & 1 )
{
crc = ( crc >> 1 )^0xa001;
}
else
{
crc >>= 1;
}
}
crc16_t[i] = crc;
}
}
void crc16_begin( void )
{
crc = 0;
}
void crc16_calc( byte c )
{
crc = ( crc >> 8 )^crc16_t[(byte)( crc^c )];
}
unsigned int crc16_get( void )
{
return( crc );
}
********************************************************

「>>」はビット演算子の右シフトですよね。
でも「^」これはビット演算子の排他的論理輪ではないのでしょうか?
本を探してみたのですが「^」はそれ以外の意味が
載っていませんでした。他にも違う演算ができるのでしょうか?
本来もっと勉強してから質問しなくてはならないのですが、
どうしても時間がないものですから、
どうぞよろしくお願いいたします。

No.2162

Re:伝送制御コード(通信の基礎)について
投稿者---ともじ(2002/07/23 18:55:47)


>PSBさんが指摘してくれましたcrc16_get()という関数が
>明確に見つけられなかったのですが、それらしき場所の
>ソースは以下のようになっています。

crc16_get()は提示したソースの最後にありますね。

>「>>」はビット演算子の右シフトですよね。
>でも「^」これはビット演算子の排他的論理輪ではないのでしょうか?

>>は右シフトで、^は排他的論理和でいいです。

ただ、CRC演算部分はそのまま使えるので、このソースを解析する
必要は無く、最初に提示したソースをどのように利用するかが重要なのでは
ないでしょうか。
#むろん、時間があれば解析すれば勉強になります。

最初のソースにおおよそのコメントを入れてみました。
この流れでデータ送信を行えば、いいと思いますが。

        rs_putc( SC_DLE );              /* DLE送信 */
        rs_putc( SC_STX );              /* STX送信 */
        ch = Snd.bno & 0xff;    /* bnoの下位1バイトを取り出し */
        if( ch == SC_DLE ){
                rs_putc( SC_DLE );
        }
        rs_putc((unsigned char)ch );    /* bno送信 */
        ch = ~ch;                               /* bnoのビット反転 */
        if( ch == SC_DLE ){
                rs_putc( SC_DLE );
        }
        rs_putc((unsigned char)ch );    /* bnoの補数送信 */
        crc16_begin();                  /* CRC演算開始 */
        Snd.cp = Snd.rp;
        for( i = 0;( i < 256 )&&( Snd.cp < Snd.wp );i++ ){
                ch = Snd.buf[Snd.cp];           /* テキスト取り出し */
                if( ch == SC_DLE ){
                        if( i == 255 ){ 
                                break;
                        }
                        rs_putc( SC_DLE );
                        i++;
                }
                crc16_calc((byte)ch);           /* CRC演算 */
                rs_putc((unsigned char)ch );    /* テキスト送信 */
                Snd.cp++;                               /* インデックス更新 */
        }
        rs_putc( SC_DLE );              /* DEL送信 */
        rs_putc( SC_ETX );              /* ETX送信 */
        crc = crc16_get();              /* CRC取得 */
        rs_putc((unsigned char)(( crc >> 8 ) & 0xff));  /* CRC上位8ビット送信 */
        rs_putc((unsigned char)(crc & 0xff));           /* CRC下位8ビット送信 */


No.2166

Re:伝送制御コード(通信の基礎)について
投稿者---ゆき(2002/07/24 10:04:36)


ともじさん、詳しい解説ありがとうございます。
お陰様で、だいぶ全体像が見えてきました。
しかし、通信がこんなにややこしいことになっているとは
全く知りませんでした・・・。CRC演算、難しいです・・・。

 ENQから始まり、DLEやブロックナンバー(bno)を送信したり
というのは分かりましたが、まだ、bnoのビット反転やbnoの補数送信、
CRC上位(下位)8ビット送信については、手持ちの書籍には
書いてませんでした。ネットで探そうと思いますが、
これは通信における決まり事なのでしょうか?
単に、サーバー側でそう仕様を決めてるだけなのかも知れませんが。

 それから、実はこの解析の次には、このCをVBで実現する!
という作業が待っています・・・。VBでフォームなどを作り、
その画面で他のプログラムなども管理する仕組みを作ります。
Cの通信がVBに変換不可能となると、通信だけはCで繋いで、
VBからファイルを送受信するなんてことをしなくてはいけませんが、
そんなことは可能なのでしょうか?

長くなりましたが、以上よろしくお願いします。

No.2169

Re:伝送制御コード(通信の基礎)について
投稿者---ともじ(2002/07/24 17:54:33)


こんにちは。

>しかし、通信がこんなにややこしいことになっているとは
>全く知りませんでした・・・。CRC演算、難しいです・・・。

ベーシック手順は、ベーシックと言うぐらいですから、本当に基本で
やさしい部類だと思いますよ。CRC演算も、データを多項式に
見なして、あらかじめ決められている多項式で割った余りをビットに
直し、CRC符号に使っているだけです。
データを多項式に見なす、というのは、例えばデータが
"AB":01000001 01000010 だとすると、
0*X15 + 1*X14 + ・・・1*X1 + 0*X0
と見なすということです。

> ENQから始まり、DLEやブロックナンバー(bno)を送信したり
>というのは分かりましたが、まだ、bnoのビット反転やbnoの補数送信、
>CRC上位(下位)8ビット送信については、手持ちの書籍には
>書いてませんでした。ネットで探そうと思いますが、
>これは通信における決まり事なのでしょうか?
>単に、サーバー側でそう仕様を決めてるだけなのかも知れませんが。

データの並びは基本は同じでしょうが、システムにより若干違いが
あると思います。決め事ですから、そのとおりに返せばいいと思いますが。
というより、仕様書があって、それに従ってプログラムは作るべきで
解析して云々というのはちょっとおかしいですよね。最初のプログラムに
コメントも入っていないようですし、これは先が大変そうですね。

CRCについては2バイトで算出して、2バイトいっぺんには送信できない
ので、上位下位に分けて1バイトづつ送信しているだけでしょう。

>Cの通信がVBに変換不可能となると、通信だけはCで繋いで、
>VBからファイルを送受信するなんてことをしなくてはいけませんが、
>そんなことは可能なのでしょうか?

VBで画面を作り、内部処理はCでというのはよくある話ですね。


No.2188

Re:伝送制御コード(通信の基礎)について
投稿者---ゆき(2002/07/25 21:05:31)


こんにちは。
ともじさん毎回ご返答ありがとうございます。

 原因は知りませんが、そのソースは何人かの手によって
書かれたものです。ある程度のコメントは入っていますが、
長いことほったらかしだったのか、仕様書が少ないのです。
作成したときはいいですが、後々のことを考え、やはり
仕様書なりはきちんと整理し保存しておくべきですよね。

 まだまだお聞きしたいことが山ほどありますが、
お蔭様で少しずつ解析&作成も前進していますので、
もっとポイントを絞ってご質問なりできるよう
がんばってみようと思います。
そのときはまたよろしくお願いいたします。

 ありがとうございました。