例えば、Makefileの
server.o: server.c common.h
という行は「server.oを作成するためには、server.cとcommon.hというソースファイルが必要」という依存関係を示しています。
例 (ls.cgi)
#!/bin/sh
ls -lR $HOME
実行権限を出しておくことを忘れないように。
% chmod +x ls.cgi
request-header = "Host" ":" host [ ":" port ]
となっていますが、その直後の例では、
HOST: www.hogehoge.com:80
と、HOST:の後に空白文字が入っています。
正しくは定義の通り、HOST:の後に空白を入れる必要はありませんが、入れてもその空白を無視するように実装されているのが普通なようです。(参考資料の4.2章 メッセージヘッダでは、このような空白は削除される「であろう」と書いてあります:-( )
この実験では、空白を入れても入れなくてもかまいません。とくにサーバ側では、どちらか一方のやり方のみを受理できればよいものとします。
例:
FILE *fp;
fp=fdopen(s,"r+");
fgets(buf, sizeof(buf), fp);
fflush(fp);
fputs(buf, fp);
fflush(fp);
fgets(buf, sizeof(buf), fp);
% server 60001
などと実行させたい場合、この「60001」のような引数はmain関数の引数として渡すことができます.
例:
int main(int argc, char *argv[]) {
...
}
このようにすると、argcに「引数の個数」が、argvに「引数の列(文字列の配列として)」が格納されます。
この場合、実行しようとしているコマンド名自体も「0番目の引数」として扱われるので注意が必要です。上の例をコンパイルして実行ファイルexampleを作成し、
% example abc def
と実行すると、mainの本体において、argcの値は「3」に、配列argvの値は0番目が「example」、1番目が「abc」、2番目が「def」という文字列になります。
例えば、
client.c:
...
send(s, "Message", 7, 0);
...
server.c:
...
fgets(buf, sizeof(buf), f);
...
などで、サーバが受け取った文字列 Message をbufに格納しようとすると、fgetsは Message を読み込んだ後、さらなる入力を待ち続けます。
文字列 Message を受信した段階でbufに格納したい場合は、送信側で"Message\n"と改行文字をつけて送信する(この場合、サーバ側で改行文字を再度取り除く必要がある)か、または、sendするバイト数を8とするなどして文字列の終端文字を含めて送信することにより、fgetsにメッセージが終了したことを伝える必要があります。
例(fooを出力後、1秒待ってからbarを出力する):
printf("foo\n");
sleep(1);
printf("bar\n");
対応策としては次が考えられます。
(1) sendでのサイズ指定は send(buf,sizeof(buf),fp) などとせずに、send(buf,strlen(buf),fp)などとする。(sizeofを使うと、bufの長さに足りない部分はメモリ上の予期しない内容が送信されてしまう。)
(2) sendではなく、fputsなどを利用する。
% man 2 accept
とします。