第 3 回ネットワークプログラミング

23
第 3 第第第第第第第第第第第第 第第 第第 第

Upload: hakan

Post on 22-Jan-2016

59 views

Category:

Documents


0 download

DESCRIPTION

第 3 回ネットワークプログラミング. 中村 修. 今日のお題. ディスクリプタ file I/O 練習問題1: cat –n を作ってみよう ポインタ ポインタと文字列 練習問題2:ファイルの中身をひっくり返してみよう 引数 argc,argv 練習問題3: 引数を出力しよう -------- (休憩) ----------------- 実習 cat –n –r file1 file2 file3 ……  を作ろう. ファイルディスクリプタ. プロセスが外の世界と通信するためのデータの入り口 全ての通信は、必ずファイルディスクリプタを通じて行われる - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第 3 回ネットワークプログラミング

第 3回ネットワークプログラミング

中村 修

Page 2: 第 3 回ネットワークプログラミング

今日のお題 ディスクリプタ

file I/O 練習問題1: cat –n を作ってみよう

ポインタ ポインタと文字列 練習問題2:ファイルの中身をひっくり返してみよ

う 引数

argc,argv 練習問題3: 引数を出力しよう   -------- (休憩) -----------------

実習 cat –n –r file1 file2 file3 ……  を作ろう

Page 3: 第 3 回ネットワークプログラミング

ファイルディスクリプタプロセスが外の世界と通信するためのデータの入り口全ての通信は、必ずファイルディスクリプタを通じて行われる

(予約済)0: 標準入力(キーボード)

1: 標準出力(モニタ) 2: 標準エラー出力(モニタ)

Page 4: 第 3 回ネットワークプログラミング

入出力関数 :システムコール open read write close

次のページから例あり

Page 5: 第 3 回ネットワークプログラミング

open()システムコール int open(char *path, int flags, …);

返り値がファイルディスクリプタ 引数は基本的に 3 つ

char *path 開くファイルのパス名が保存されている文字配列 ( への

ポインタ ) int flags

ファイルを開くときにどのような状態で開くかを決める 読み込みだけ (O_RDONLY) 書き込みだけ (O_WRONLY) 読み書き両方 (O_RDWR) 追加 (append) (O_APPEND) 新規作成 (O_CREAT) ブロックしない (O_NONBLOCK)

3 番目は便宜的に 0

Page 6: 第 3 回ネットワークプログラミング

read()システムコール

int read(int d, void *buf, size t nbytes) 引数

int d: ファイルディスクリプタ void *buf: 読み込んだデータを保存するための配列 ( バッファ ) size_t nbytes: 1 回の read() で読める最大バイト数 ( バッファの

大きさ ) 返り値

int: 実際に読み込んだバイト数 0 より大きい: 読み込み成功 0 : ファイルの最後 (EOF) に到達 0 より小さい: エラー

Page 7: 第 3 回ネットワークプログラミング

write()システムコール int write(int d, void *buf,size t nbytes)

引数 int d: ファイルディスクリプタ void *buf: 書き込むデータを保存している配列・ポインタ

( バッファ ) size_t nbytes: 1 回の write() で書き込むバイト数 ( 書き込む

データの大きさ )

返り値 int: 実際に書き込んだバイト数

0 より大きい: 書き込み成功 0 より小さい: エラー

Page 8: 第 3 回ネットワークプログラミング

close()システムコール int close(int fd);

引数 int fd: ファイルディスクリプタ

返り値 0:  成功 0 より小さい: エラー 通常はあまりチェックしない

Page 9: 第 3 回ネットワークプログラミング

open()/read()/write()/close()の例#include <fcntl.h>#include <sys/types.h>#include <sys/uio.h>#include <unistd.h>#define BUFSIZE 1024

int main(){ char buf[BUFSIZE]; int fd; int nbyte; fd = open(“test.txt”, O_RDONLY, 0); while((nbyte = read(fd, buf, BUFSIZE)) > 0) { write(1, buf, nbyte); } close(fd); exit(0);}

Page 10: 第 3 回ネットワークプログラミング

ファイルを扱う関数 fopen(char *filename, char *mode)

r,w,a,r+,w+,a+ fgets(cahr *s,int length,FILE *fd) fgetc(FILE *fd) fclose(FILE *fd)

次のページに練習問題あり

Page 11: 第 3 回ネットワークプログラミング

これらの関数を使うと#include <stdio.h>int main(){ FILE *fp; char buf[1024]; int c; fp = fopen(“sample.txt”,"r");

while((fgets(buf, sizeof(buf),fp)) != NULL){ fputs(buf,stdout); } fclose(fp); exit(0);}

Page 12: 第 3 回ネットワークプログラミング

練習問題 1

-n オプションを指定した cat コマンドのように、左端に行番号を出力するようなプログラム catn.c を作成するsample.txt を読み込んで 行番号を付けて出力。

sample.txt /home/kaizaki/osamuNP/3/sample.txt

次のページから「ポインタ」解説

Page 13: 第 3 回ネットワークプログラミング

ポインタ"T""h""i""s"" ""i""s"" ""t""e""s""t"

メモリ空間100

101

102

103

104

105

106

107

108

109

110

111

アドレス

"."112

113

char string[] = "This is test.";

100200

….201

NULL

char *s = string;

string[]

"で括った文字列はどこかに格納されている

ポインタ変数: メモリアドレスを格納している          変数型: ポインタが示すメモリにどの型で格納さ   れているかを示す   cf char *s; 文字 ( 列 ) が入っている変数           のアドレスが入る変数

Page 14: 第 3 回ネットワークプログラミング

文字列とポインタ

文字列は配列で管理されている      char mystr[8] = “hello”;

      char *mystr = “hello”;

h e l l o \0

h e l l o \0

*mystrmystr[0]

*(mystr+1)mystr[1]

*(mystr+2)mystr[2]

*(mystr+3)mystr[3]

*(mystr+4)mystr[4]

mystr = “hello”mystr + 1 = “ello”mystr + 2 = “llo”mystr + 3 = “lo”mystr + 4 = “o”

Page 15: 第 3 回ネットワークプログラミング

文字配列と文字定数とポインタ

文字配列   char str1[8] = “hello”;8つの文字変数からなるstr1という配列を用意

ポインタ   char *ptr = “hello”;

str1

h e l l o \0“hello” どこかに存在する

h e l l o \0配列に対して「どこかに存在している」” hello”の内容をコピー (初期化 )

文字変数を指すポインタ型変数 ptr を用意

ポインタ変数に対して「どこかに存在している」”hello”のアドレスをコピー (初期化 )

0xff0120

文字列定数 宣言時にどこかに存在する (無名配列 )

str1

ptr

ptr

Page 16: 第 3 回ネットワークプログラミング

ポインタが役に立つ時は? ポインタの利用例

動的に割り当てた配列 (malloc() など ) 複数ある類似の変数への汎用なアクセス 関数引数の ( 擬似的な ) 参照渡し (call by reference) あらゆる種類のデータ構造を動的に割り付ける

cf ツリー構造、リンクリスト 配列や効率のよい参照渡しのコピー

関数引数の場合

次のページに練習問題あり

Page 17: 第 3 回ネットワークプログラミング

練習問題 2

sample.txt ファイルの内容をひっくり返して、 anagram.txt  という名前のファイルを作成する。

abcdefghijkl : :

fedcbalkjihg : :

Page 18: 第 3 回ネットワークプログラミング

コマンドライン引数: argc,argvコマンドの引数を用いるには ?

cat –n filecat file1 file2 file3

Page 19: 第 3 回ネットワークプログラミング

コマンドライン引数の利用法 main( int argc, char **argv) main( int argc, char *argv[])

argc  には引数の数 argv[0] にはコマンド名 argv[1] には 1 番目の引数 argv[2] には 2 番目の引数

Page 20: 第 3 回ネットワークプログラミング

練習問題3 argc,argv を用いて引数を全て出力する。 実行例 / 出力例

%./a.out 123 456 789

arg[0]: ./a.out

arg[1]: 123

arg[2]: 456

arg[3]: 789

Page 21: 第 3 回ネットワークプログラミング

練習問題 3の回答#include<stdio.h>

int main(int argc, char *argv[]){

int i; for(i = 0; i < argc; i++){ printf("arg[%d]: %s\n", i, argv[i]); }

}

Page 22: 第 3 回ネットワークプログラミング

実習 今日作成した、

cat –n cat –r (中身をひっくり返す ) 引数を出力する関数

を参考に、以下の書式を満たす catを作成する   cat –r cat –n cat file1 file2 file3 複数のオプションを同時に満たす機能を実現できたらボーナス得点。

Page 23: 第 3 回ネットワークプログラミング

実習ヒント -r –n などは  2 通りでチェックできる

if(*argv[i] == ‘-’ && *(argv[i]+1) == ‘r’ ) if(argv[i][0] == ‘-’ && argv[i][1] == ‘r’)

fopen でファイルを開いたら、かならず fclose