- PR -

C言語 ネットワークプログラミングでのCRLF送信

1
投稿者投稿内容
dam
会議室デビュー日: 2004/11/07
投稿数: 13
投稿日時: 2007-02-20 10:47
damと申します。
ネットワークプログラムの学習目的で
C言語によるPOPクライアント作成を
Debian GNU/Linux上で行なっています。

改行コードの送信についてご教示ください。

デバッグ用に標準入力から文字列を受け取り
POPサーバへコマンドを送りたいと考えています。

コマンドを送信する際、改行コードをCRLFにしなければ
なりません。

標準入力から
read(0, buf, sizeof(buf));
にてコマンドをbufに格納しようとしています。

ktermにて
user foo\r\n [Enter]と入力した場合、
bufの中に、user foo\\r\\n\n と格納されてしまいます。

送信時に user foo\r\nとするにはどのように
するのが一般的でしょうか?

私が試したのは方法は以下の通りです。

(1) 入力の際にuser foo\r\n [Enter] とする。
bufには user foo\\r\\n\nが格納される。
strtok(buf, "\\r\\n")を実施し、
user foo\0に変換。
その後、strcat(buf, "\r\n")を行ない
user foo\r\nの形式にして送信。
※ strtokにて、\\r\\nにマッチせず、
use\0となってしまい、失敗しました。

(2) 入力の際にuser foo [Enter] とする。
bufには user foo\nが格納されるので、
buf[strlen[buf]] = '\0'を実施し、
user foo\0に変換。
その後、strcat(buf, "\r\n")を行ない
user foo\r\nの形式にして送信。
※ この方法はうまくいきました。

またネットワークプログラミングにおける
上記のような改行コードの取り扱い方法について
記載されている書籍、Webについての
情報をいただけると喜びます。

よろしくお願いします。

_________________


[ メッセージ編集済み 編集者: dam 編集日時 2007-02-20 20:27 ]
dam
会議室デビュー日: 2004/11/07
投稿数: 13
投稿日時: 2007-02-20 11:42
追記

\r\nを標準入力から
入力したいときは、[Ctrl+m][Enter]を押すべきかと思い
やってみましたが、
[Ctrl+m]とした時点で、\nが格納されてしまいました。
うーむ。

[ メッセージ編集済み 編集者: dam 編集日時 2007-02-20 14:37 ]
ぽんす
ぬし
会議室デビュー日: 2003/05/21
投稿数: 1023
投稿日時: 2007-02-20 19:55
自分はあまり気にしてません。
入力されたLFをCRLFに変換する(2)の方針は、単独のLFを送出する必要が
ない限りうまく行くし、実際、必要ないケースが多いですよね。

あと、サーバ側でLFが送られてきたらCRLFとみなすようになっている
ことも多いので、特になにもせずそのままLFを送ってしまう、とか。
LFとCRLFとで挙動が異なるかどうかテストしたい、というのでなければ
これでもO.K.

[ メッセージ編集済み 編集者: ぽんす 編集日時 2007-02-20 20:08 ]
dam
会議室デビュー日: 2004/11/07
投稿数: 13
投稿日時: 2007-02-20 21:16
ぽんすさん
ご返答ありがとうございます。

おっしゃられるように
単独のLFを送出する必要がないのであれば、
送信する際に、LFをCRLFに変換して送ってしまえば
済む話ですね。

文字列では"user foo\r\n"という記述ができるので、
標準入力からも、同じような感じで
実現できるのでは?と考えていましたが、
標準入力からキーボードでCRLFを入力する方法は
見つかりませんでした。
→ つまり、\r\nという記述を使いたいのであれば、
\\r\\n\nとして格納されたデータを
\r\nに変換しなおす必要があるわけで、
LF→CRLFに直すよりも手間がかかりますね。

デバッグ目的の利用で統一感を出すためだけに
その機能を実装するのは、あんまり意義が無い、、、。

ローカル環境であれば、LFを送信して、
サーバがCRLFとみなした対処してくれることを
期待するのもありだと思いますが、
今回はネットワークに繋がるのを前提とした
プログラムの作成を目的としていますので、
やはり規約どおりにCRLFにして送信したいと思います。
※ どうしてLFを送っているのに、サーバ側から正しい応答が
返ってくるのか不思議でしたが、納得できました。

非常にすっきりしました。
ありがとうございました。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2007-02-21 02:09
引用:

\r\nを標準入力から
入力したいときは、[Ctrl+m][Enter]を押すべきかと思い
やってみましたが、
[Ctrl+m]とした時点で、\nが格納されてしまいました。


stty -icrnl
しておけばOK。
ただし、入力方法は[CTRL+M][CTRL+J]です。

デバッグ用の機能なら、ソフトの方は read したデータをそのまま送信することにして、
CRLFを入力できるように事前にsttyを変更してやるのが簡単で融通が効きます。

ただし、この状態だと[Enter]キーはCRであってLFではない。
1行のreadを完了させるには[CTRL+J]をタイプする必要がある点にご注意を。
dam
会議室デビュー日: 2004/11/07
投稿数: 13
投稿日時: 2007-02-21 23:07
coasmさん
ご返答ありがとうございます。

お教えいただいた方法を参考にして
プログラム中、ioctl()を使い、
実現できるのを確認できました。

※ 掲示いただいたstty -icrnlの情報から、
端末属性の変更について
河野清尊氏のC言語によるUNIXシステム
プログラミング入門(オーム社)を
調べました。

デフォルトでは
Enterキー(Ctrl+m)はCRを入力するためのキーであり、
Ctrl+jはLFを入力するためのキーであること。

また、端末属性によって
端末からの入力時、
CR→LFに変換されており、
端末への出力時、
LF→CRLFに変換されているということを初めて知りました。

利便性を考え、今回のPOPクライアントのデバッグ目的では
LF→CRLFとなるよう、ソースを変更して対処しましたが、
いただいた情報、大変参考になりました。

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

スキルアップ/キャリアアップ(JOB@IT)