• 検索結果がありません。

1 : telnet WWW telnet WWW URL (html ) ( URL ) [Kenta-Oshiro:network/slab2-np/rep01] j06012% telnet 80 nkf -e GET /index.html HTTP/1

N/A
N/A
Protected

Academic year: 2021

シェア "1 : telnet WWW telnet WWW URL (html ) ( URL ) [Kenta-Oshiro:network/slab2-np/rep01] j06012% telnet 80 nkf -e GET /index.html HTTP/1"

Copied!
20
0
0

読み込み中.... (全文を見る)

全文

(1)

情報工学実験

II

ネットワークプログラミング基礎

担当教員 : 長田智和

組名:Fri

学籍番号 :

065712D

名前

:

大城健太

実験日12月7日

提出日12月26日

締切日12月21日

(2)

1

課題1

: telnet

コマンドによる

WWW

サーバへのアクセス

• telnet コマンドを使って任意の WWW サーバにアクセスし、任意の URL のページデータ (html ソースプログラ

ム) を画面に表示せよ。(報告書にはその URL とページデータの先頭の20行程度を添付せよ。)

• 実行結果

[Kenta-Oshiro:network/slab2-np/rep01] j06012% telnet www.u-ryukyu.ac.jp 80 | nkf -e GET /index.html HTTP/1.0

Connection closed by foreign host. Trying 133.13.7.96...

Connected to www.u-ryukyu.ac.jp. Escape character is ’^]’.

HTTP/1.1 200 OK

Date: Tue, 11 Dec 2007 11:31:51 GMT sin: Apache/2.0.52 (Red Hat)

Last-Modified: Tue, 11 Dec 2007 02:58:20 GMT ETag: "53cc30-2969-e29fcb00"

Accept-Ranges: bytes Content-Length: 10601 Connection: close Content-Type: text/html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <meta http-equiv="Content-Script-Type" content="text/javascript" /> <title>琉球大学公式ホームページ</title>

<style type="text/css">

<!--td { font-size: smaller; } a img{ border: none; } #image_title{ font-size: small; text-align: center; color: #B63B3B; } --> </style>

<link href="preview/ryudai2.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="/js/prototype.js"></script>

<script type="text/javascript" src="/js/scriptaculous.js?load=effects"></script> <script type="text/javascript" src="/js/lightbox.js"></script>

<link rel="stylesheet" href="/css/lightbox.css" type="text/css" media="screen" / >

(3)

2

課題2

: inetd

を使用するサーバプログラムの作成

• サンプルプログラム (1) はサーバ (sin.c) を inetd から起動することで、サーバはクライアント (client.c) の標準入力から

入力された文字に対応するキーワードをクライアントに返すプログラムである。サンプルプログラム (1) を自分の実験 環境で動作するようにし、実行結果を示すとともに、プログラムの中で使われている関数 (Connect,Disconnect,Send Data,Recv Dataなど) の動作を説明し、クライアント・サーバの動作全体を動作フロー図を示して説明せよ。

• xinetd の設定

inetdを起動することができなかったため、inetd の拡張版である xinetd を用いる。その際に設定した作業を下に示す。 なお、このやり方は j06001 の Kazuki AKAMINE 君がニュースに挙げていたものを参照している。

• sin.c をコンパイルして、バイナリファイル sin を作成しておく。 • 設定ファイル services にサービスを追加する。

% sudo emacs -nw /etc/services を実行して、

tcpinetd 5682/tcp の一行を追加する。

• tcpinetd の設定ファイルを xinetd.d 内に作成する。

% sudo emacs -nw /etc/xinetd.d/tcpinetd

を実行して、各自の環境に合わせてバイナリファイル sin へのフルパスを指定する。

• xinetd を起動するようにする。

% sudo emacs -nw /System/Library/StartupItems/IPServices/IPServices を実行して、

/usr/sbin/xinetd -inetd compat -pidfile /var/run/xinetd.pid を StartService() の中に追加する。

• 設定を反映させる。

% sudo /System/Library/StartupItems/IPServices/IPServices start を実行して設定を反省させる。

• sin.c の追加したところ

#include <stdlib.h> ・・・・exit() 関数を使っているため。

#define DATAFILE "/Users/j06012/INFO-jikken2/network/data"

• client.c の追加したところ

#include <stdlib.h> ・・・・exit() 関数を使っているため。 #define HOST_NAME "localhost"

(4)

[Kenta-Oshiro:~/INFO-jikken2/network] j06012% ./client Connected.

Input Keyword = warning: this program uses gets(), which is unsafe. yama

Keyword = [yama] / Data = [kawa] Input Keyword = xyz

Keyword = [xyz] / Data = [XYZ] Input Keyword = 123

Keyword = [123] / Data = [456] Input Keyword = xxxx

Keyword = [xxxx] / Data = [yyyy] Input Keyword = shiro

Keyword = [shiro] / Data = [kuro] Input Keyword = ^C

• 関数の説明

• Connect():ソケットの生成を行い、host name や host address の設定をして、サーバにコネクションを要求する

関数 • Disconnect():コネクションを閉じる関数 • SendData():サーバにデータを送信する関数 • RecvData():サーバからデータを受信する関数 • GetLineFromPeer:クライアントからデータを受信する関数 • GetKeywordData:入力された文字列と Data の対応する文字列を返す関数

(5)

動作の流れを以下の動作フロー図に示す。

Client

Server

Connect() 通信路を確立 xinetd() serverの呼び出し リクエスト レスポンス コネクションの確立 SendData() write() GetLineFromPeer() read() データの送信 GetKeywordData() fopen(), fclose() RecvData() read() データの送信 データの受信 Disconnect() close() xinetd() 閉じる ソケットの終了 図 1: サーバとクライアントの動作フロー図

3

課題3

:inetd

を使用しないサーバプログラムの作成

• サンプルプログラム (1) のサーバプログラム (sin.c) を inetd から起動するものであるが、inetd を使用せずに同じ

動作をするデーモン型のサーバプログラムを作成し、実行結果を示すとともに、inetd を使用するサーバプログラ ムとそうでないものとの実装上の違い説明せよ。 • myserver.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/errno.h> #include <string.h> #include <ctype.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h>

#define DATAFILE "/Users/j06012/INFO-jikken2/network/slab2-np/rep01/ex3/data2" #define DELIMITS " \t\n\r" /* \t:タブ, \n:改行, \r:リターン */

(6)

#define SERVICE_NAME "tcpinetd2"/* /etc/services内に指定したサービス名を指定 */ #define PROTOCOL "tcp"

char datavalue[256]; /* client に返す単語を格納する配列*/ int GetLineFromPeer(char *line, int socket_num) {

int i; for(i=0;;) {

if(1 != read(socket_num, line+i, 1)) continue; else { i++; line[i] = ’\0’; } if(’\n’ == line[i-1]) return i; } }

char *GetKeywordData(char *key) { FILE *fp;

char buff[256];

if((FILE *)NULL == (fp = fopen(DATAFILE,"r"))) return (char *)NULL;

for(;;) { char *p; /* 1つ目のトークン (キーワードを指す)*/ char *pp; /* 2つ目のトークン (p の対応語を指す)*/ fgets(buff,256,fp); if(feof(fp)) break; if(ferror(fp)) break;

if((char *)NULL == (p = strtok(buff,DELIMITS))) //data2のキーワード continue;

if((char *)NULL == (pp = strtok((char *)NULL,DELIMITS)))//data2の対応語 continue; if(0 == strcmp(p,key)) { fclose(fp); strcpy(datavalue,pp); /* 引き数に対応する単語をコピーする */ return datavalue; }

(7)

}

fclose(fp);

return (char *)NULL; }

int main(void) {

int socket_num, new_socket_num; struct sockaddr_in serv, clit; struct servent *ServiceEntry; socklen_t sock_size = sizeof(clit); char RecvBuff[256];

/* ソケットの作成 */

if( (socket_num = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror("socket()");

exit(1); }

/* 指定した IP アドレス、ポート番号、通信方式を読み込む */

if((ServiceEntry = getservbyname(SERVICE_NAME, PROTOCOL)) == NULL) { perror("getservbyname()"); exit(1); } serv.sin_port = ServiceEntry->s_port; serv.sin_family = AF_INET; serv.sin_addr.s_addr = htonl(INADDR_ANY); /* ネットワークバイトオーダに変換 */ /* ---ここからデーモンの役割---*/ /* ソケットへアドレス情報を結びつける */

if(bind(socket_num, (struct sockaddr *)(&serv), sizeof(serv)) < 0) { perror("bind()"); exit(1); } /* 受信待機を開始する*/ if(listen(socket_num, SOMAXCONN) < 0) { perror("listen()"); exit(1); } for(;;) { /* クライアントからの接続が閉じられてもループし続ける */ /* クライアントからの接続要求を受けると接続を確立する */ if((new_socket_num =

accept(socket_num, (struct sockaddr *)(&clit), &sock_size)) < 0) { perror("accept()");

(8)

} /* クライアントからのデータに返答し続ける */ for(;;) { char *p; char SendBuff[256]; char *pp; (void)GetLineFromPeer(RecvBuff, new_socket_num); if(’=’ == RecvBuff[0]) { /* If End Mark */ break;

}

if((char *)NULL != (p = strchr(RecvBuff,’=’))) { *p = ’\0’; /* ’=’ を ’\0’ に変換する処理 */ if((char *)NULL == (pp = GetKeywordData(RecvBuff)))

sprintf(SendBuff, "%s=\n", RecvBuff); else

sprintf(SendBuff, "%s=%s\n", RecvBuff,pp);

(void)write(new_socket_num, SendBuff, strlen(SendBuff)); } } close(new_socket_num); /*ソケットを閉じる*/ } return 0; } • myclient.c /*** TCP Client ***/ #include <stdio.h> #include <ctype.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdlib.h>

#define SERVICE_NAME "tcpinetd2" #define PROTOCOL "tcp"

(9)

int Connect() {

int SocketNumber; /* Socket descripter */

struct servent *ServiceEntry; /* service entry */ struct hostent *HostEntry; /* host entry */ struct sockaddr_in sin; /* Socket Entry */ /* Get Service Entry by Service-Name */ if((struct servent *)NULL == (ServiceEntry = getservbyname(SERVICE_NAME,PROTOCOL))) {

printf("\7No service [%s].\n",SERVICE_NAME); exit(1);

}

/* Get Host Entry by Host-Name */

if((struct hostent *)NULL == (HostEntry = gethostbyname(HOST_NAME))) {

printf("\7No Hosts [%s].\n",HOST_NAME); exit(1);

}

/* Get Socket */

if(0 > (SocketNumber = (socket(AF_INET,SOCK_STREAM,0)))) {

printf("\7Cannot get Socket.\n"); exit(1);

}

/* Set protocol family name */ sin.sin_family = AF_INET; /* Set Host Address */

bcopy(HostEntry->h_addr,&sin.sin_addr,HostEntry->h_length); /* Set Port N.o. */

sin.sin_port = ServiceEntry->s_port;

if(0 > connect(SocketNumber,(struct sockaddr *)(&sin),sizeof(sin))) { printf("\7Cannot Connect.\n"); exit(1); } return SocketNumber; }

(10)

void Disconnect(int SocketNumber) {

close(SocketNumber); }

void SendData(int SocketNumber,char *line) { if(strlen(line) != write(SocketNumber,line,strlen(line))) { printf("\7Send Failed.\n"); exit(1); } }

int RecvData(int SocketNumber,char *line) {

int i;

for(i = 0 ;;) {

if(1 != read(SocketNumber,line + i,1)) continue; else { i++; *(line + i) = (char)0; if(((char)(’\n’)) == *(line + i - 1)) return i; } } } int main() { int Sock; char Key[256]; char Data[256]; char buff[256];

Sock = Connect(); /* Connect */ printf("Connected.\n"); for(;;) { char *p; printf("Input Keyword = "); fflush(stdout);

(11)

gets(Key);

sprintf(buff,"%s=\n",Key);

SendData(Sock,buff); /* Send It ! */ if(0 == strlen(Key))

break; /* If End Mark */

/* ---- Waiting for Server response Here --- */ (void)RecvData(Sock,buff); /* Recv It ! */ if((char *)NULL != (p = strchr(buff,’\n’))) *p = (char)0;

if((char *)NULL != (p = strchr(buff,’=’))) p++;

printf("Keyword = [%s] / Data = [%s]\n\n",Key,p); } Disconnect(Sock); /* Disconnect */ printf("Disocnnected.\n"); } • data2 oshiro kenta abc ABC 123 456 yyyy zzzz aka kuro • 実行結果 • ターミナル1

[Kenta-Oshiro:slab2-np/rep01/ex3] j06012% ./myserver & [1] 22291

[Kenta-Oshiro:slab2-np/rep01/ex3] j06012% jobs [1] + Running ./myserver

• ターミナル2

(12)

Connected.

warning: this program uses gets(), which is unsafe. Input Keyword = aka

Keyword = [aka] / Data = [kuro] Input Keyword = abc

Keyword = [abc] / Data = [ABC] Input Keyword = oshiro

Keyword = [oshiro] / Data = [kenta] Input Keyword = yyyy

Keyword = [yyyy] / Data = [zzzz]

• 考察 ・inetd(xinetd) を使用するサーバプログラムでは、クライアントから inetd に要求される度にサーバを起動する。 そのため、システムリソースを節約することができるが、サーバの起動に時間がかかるためレスポンスが遅くなる。 inetdを使用しないサーバプログラムでは、常にサーバが起動されている状態のため、レスポンスは inetd を使用 しているサーバプログラムより早くなる。しかし、常にサーバが起動状態であるためシステムリソースは増加して しまう。 ~システムリソースについて~ ・システムリソースとは、動作するアプリケーションソフトが共通して利用する、特殊なメモリ領域。

4

課題4

:HTTP

クライアントの作成

• ソケットおよび HTML を使って WWW サーバから任意の URL のページを取得し、標準出力に出力するプログラ ムを作成せよ。 [プログラム実行例] > httpget www.ie.u-ryukyu.ac.jp/index.html (以下、該当ページの html ソースが表示される) *C言語ではなくスクリプト言語を使ってスクリプト内で telnet を使うとかはダメ。 • 他に NNTP,SMTP,POP3 クライアントなどを作成した場合は加点ポイントとする。 • http get.c のソースファイル /*** TCP Client ***/ #include <stdio.h> #include <stdlib.h>

(13)

#include <ctype.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #define BUF_LEN 256 // バッファサイズ #define PORT 80 // 接続するポート番号 #define SERVICE_NAME "http" #define PROTOCOL "tcp"

void Disconnect(int SocketNumber) {

close(SocketNumber); }

void SendData(int SocketNumber,char *line) { if(strlen(line) != write(SocketNumber,line,strlen(line))) { printf("\7Send Failed.\n"); exit(1); } }

int RecvData(int SocketNumber,char *line) {

int i;

for(i = 0 ;;) {

if(1 != read(SocketNumber,line + i,1)){ continue; } else { i++; *(line + i) = (char)0; if(((char)(’\n’)) == *(line + i - 1)) return i; } } } int main() { int Sock; char path[BUF_LEN]; // 要求するパス char buff[BUF_LEN]; // サーバに送る HTTP プロトコル用バッファ

(14)

char HOST_NAME[BUF_LEN]; // 接続するホスト名 int SocketNumber; /* Socket descripter */

struct servent *ServiceEntry; // サービス (http など) を扱うための構造体 struct hostent *HostEntry; // ホスト名と IP アドレスを扱うための構造体 struct sockaddr_in sin; // ソケットを扱うための構造体

/* Get Service Entry by Service-Name */ if((struct servent *)NULL == (ServiceEntry = getservbyname(SERVICE_NAME,PROTOCOL))) {

printf("\7No service [%s].\n",SERVICE_NAME); exit(1);

}

/* Get Host Entry by Host-Name */ printf("Input www sin = "); gets(HOST_NAME);

printf("\n");

if((struct hostent *)NULL == (HostEntry = gethostbyname(HOST_NAME))) {

printf("\7No Hosts [%s].\n",HOST_NAME); exit(1);

}

/* Get Socket */

if(0 > (SocketNumber = (socket(PF_INET,SOCK_STREAM,0)))) {

printf("\7Cannot get Socket.\n"); exit(1);

}

bzero((char *)(&sin), sizeof(sin));

bcopy(HostEntry->h_addr,&sin.sin_addr,HostEntry->h_length); sin.sin_family = PF_INET;

sin.sin_port = htons(PORT);

if(0 > connect(SocketNumber,(struct sockaddr *)(&sin),sizeof(sin))) {

printf("\7Cannot Connect.\n"); exit(1);

}

(15)

printf("Connected.\n"); char *p; printf("Input Path = "); fflush(stdout); gets(path); if(0 == strlen(path)){ Disconnect(Sock); printf("Disocnnected.\n"); exit(1); } sprintf(buff,"GET %s HTTP/1.0\r\n",path); SendData(Sock,buff);

sprintf(buff,"Host: %s:%d\r\n", HOST_NAME, PORT); SendData(Sock,buff); sprintf(buff,"\r\n"); SendData(Sock,buff); /* Send It ! */ while (1){ char buf[BUF_LEN]; int size;

size = read(Sock, buf, BUF_LEN); if ( size > 0 ){

write(1, buf, size); } else { break; } } Disconnect(Sock); printf("Disocnnected.\n"); } • 実行結果 [Kenta-Oshiro:~/INFO-jikken2/network] j06012% ./http_get warning: this program uses gets(), which is unsafe. Input www sin = www.ie.u-ryukyu.ac.jp

Connected.

Input Path = /index.html HTTP/1.1 200 OK

Date: Thu, 20 Dec 2007 12:58:50 GMT

(16)

Last-Modified: Tue, 11 Dec 2007 03:40:24 GMT ETag: "14c6729-7082-7910fa00"

Accept-Ranges: bytes Content-Length: 28802 Cache-Control: max-age=60

Expires: Thu, 20 Dec 2007 12:59:50 GMT Connection: close

Content-Type: text/html <HTML>

<HEAD>

<META http-equiv="Content-Type" content="text/html; charset=Shift_JIS"> <!--<META http-equiv="Content-Style-Type" content="text/css">-->

<META http-equiv="content-style-type" content="text/css"> <LINK rel="SHORTCUT ICON" href="icon/fav-ie2.ico">

<!--<link href="feed:http://www.ie.u-ryukyu.ac.jp/rss/" rel="alternate" type="application/rss+xml" title="RSS News Feed"/>

--> ~~~~~~~~~~ 省略 ~~~~~~~~~~

5

課題5:ポートスキャンの実験

• 自分の実験環境 (端末) の使用/未使用ポート (ウェルノンウンポートのみで ok) を確認するポートスキャンプログ ラムを作成せよ。さらに、任意のリモート端末の使用/未使用ポートを確認するゆに改良せよ (加点ポイント)。な お、スクリプト言語を使って内部で’netstat -l’ コマンドを実行し、その結果を利用するのは不可とする (あくまで もソケットプログラムを作成すること)。 (注意) リモート端末へのボートスキャンは、重要なサーバに対して決して行わないこと! • scan port のソースファイル #include <stdio.h> #include <ctype.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdlib.h>

#define SERVICE_NAME "tcpinetd" #define PROTOCOL "tcp"

#define HOST_NAME "localhost" #define BUF_LEN 256

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

(17)

int servsoc;

struct hostent *servhost; // ホスト名と IP アドレスを扱うための構造体 struct sockaddr_in sin; // ソケットを扱うための構造体

char host[BUF_LEN]; unsigned short port;

printf("Input host : "); gets(host); printf("\n"); /* ホストの情報 (IP アドレスなど) を取得 */ servhost = gethostbyname(host); if ( servhost == NULL ){ fprintf(stderr, "[%s] から IP アドレスへの変換に失敗しました。\n", host); return(0); } bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET;

bcopy(servhost->h_addr, &sin.sin_addr, servhost->h_length); /* well known port を探索 */

for(i=0; i<1024; i++) { sin.sin_port = htons(i);

if((servsoc = (socket(AF_INET, SOCK_STREAM, 0)) < 0)) { printf("\7Cannot get Socket.\n");

exit(1); }

if(connect(servsoc, (struct sockaddr *)(&sin), sizeof(sin)) < 0) { } else { printf("Port %d is open\n",i); } close(servsoc); }

printf("\nPort Scan end\n"); printf("Disocnnected.\n"); }

• 実行結果

[Kenta-Oshiro:~/INFO-jikken2/network] j06012% ./scan_port warning: this program uses gets(), which is unsafe.

(18)

Input host : www.ie.u-ryukyu.ac.jp Port 22 is open Port 80 is open Port 106 is open Port 111 is open Port 311 is open Port 389 is open Port 427 is open Port 443 is open Port 548 is open Port 625 is open Port 1010 is open Port 1012 is open Port 1013 is open Port Scan end Disocnnected.

6

課題6:バッファオーバーフローの実験

• サンプルプログラム (2) を確認せよ (このプログラムは最近のコンパイラでコンパイルして実行するとはできない)。 このプログラムは gets() 関数を用いて、標準入力からの入力をバッファにデータを読み込むものであるが、プロ グラムを実行するとプログラム中で操作していないバッファdmy[]に値が入ることがある。この原因を考察せよ (ヒント:gets[]関数の仕組みを調べよ)。また、このプログラムを修正し、正しくコンパイルして前述の動作 を実行できるようにせよ。さらに、gets[]関数のような脆弱なコードを含むプログラムによって引き起こされる TCP/IP通信におけるセキュリティ上の欠陥はどのようなものが考えられるか、具体例を挙げて説明せよ。 • 実行結果 [Kenta-Oshiro:~/INFO-jikken2/network] j06012% ./bufovf before buf(Len:0) = dmy(Len:0) =

warning: this program uses gets(), which is unsafe.

hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge after buf(Len:64) = hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge dmy(Len:0) = Segmentation fault • 考察

bufovf.cの BUFLEN の値を 30 にして実行をした結果、上記のように Segmentation fault を起こした。gets() 関 数は読み込み時に、文字列のサイズを指定できないため、バッファのサイズをオーバーしても書き込み続けてしま う。その結果、dmy[] に値が入ることになる。

(19)

この解決策として、gets() 関数の代わりに、読み込むデータのサイズを指定することができる fgets() 関数を用い ると良いと考えられる。

• サンプルプログラムの修正したところ

#include <stdlib.h>・・・・exit() 関数を使っているため。

#include <string.h>・・・・memset() 関数,strlen() 関数を使っているため。

if ((rtn = gets(buf)) == NULL) の行を if ((rtn = fgets(buf,BUFLEN,stdin)) == NULL) にする。

• 実行結果 [Kenta-Oshiro:~/INFO-jikken2/network] j06012% ./mybufovf before buf(Len:0) = dmy(Len:0) = hogehogehogehogehogehogehogehogehogehogehogehogehogehogehogehoge after buf(Len:29) = hogehogehogehogehogehogehogeh dmy(Len:0) = 以上の結果から、指定しているバッファサイズの30をオーバーせずに文字列が書き込んでおり、それ以降の文字列 は見ないようになっていることがわかる。 • セキュリティ上の問題について このようにして、メモリサイズを超えて文字列が入力されてオーバーフローがおこると、確保したメモリ領域以外 の領域にデータが入力される。この結果、データが入力される領域が何かのデータ領域だったり、何かのプログラム だった場合、不具合が起きる可能性がある。このことを利用し、バッファに対してオーバーフローが起こるような 量のデータを送り付けてシステムやプログラムの機能停止にしたり、オーバーフローが起こったプログラムのアク セス権限で任意の動作をさせることができる。 このようにバッファオーバーフローを使い、それに伴ってできたセキュリティホールを突けば、ウイルスを起動され ることもできてしまう。バッファオーバーフローは、最も代表的なセキュリティホールであり、さまざまな OS やア プリケーションに多く存在している問題である。

7

課題7

(

オプション

)

• tcpv6c は IPv4 と IPv6 の両方に対応しているにもかかわらず、tcpc(IPv4 のみに対応)よりコードが短い。この

理由は何故か説明せよ。(ヒント:両プログラムのアドレスとポート番号の変換処理部分に着目せよ)

(20)

tcpc.cでは、gethostbyname() でサーバの IP アドレスを調べ、getservbyname() でサーバのポート番号を調べ ている。一方で、tcpv6c.c では getaddrinfo() でサーバの IP アドレスとポート番号を両方とも調べている。これ は、tcpc.c では2つの関数を利用して行っている処理に対して tcpv6c.c では1つの関数で行っていることになり、 この結果、tcpv6c.c は tcpc.c より短いコードとなる。

・getaddrinfo() について (JM Project 参照)

getaddrinfo()関数は、4つの関数 getipnodebyname(), getipnodebyaddr(), getservbyname(),

getservbyport()の機能をまとめて1つのインターフェースにしたものである。getaddrinfo() 関数はスレッド セーフで、ひとつ以上のソケットアドレス構造体を生成する。 この構造体は bind() や connect(2) などの関数 コールでクライアント用・サーバー用のソケットを生成する際に 用いることができる。

8

参考文献

[1]JM Project http://www.linux.or.jp/JM/ [2]Wikipedia http://ja.wikipedia.org/wiki/メインページ [3]ソケットの使用法 http://www.multisoft-lab.com/voicechat/socket.html

参照

関連したドキュメント

図2に実験装置の概略を,表1に主な実験条件を示す.実

SVF Migration Tool の動作を制御するための設定を設定ファイルに記述します。Windows 環境 の場合は「SVF Migration Tool の動作設定 (p. 20)」を、UNIX/Linux

・「下→上(能動)」とは、荷の位置を現在位置から上方へ移動する動作。

アンチウイルスソフトウェアが動作している場合、LTO や RDX、HDD 等へのバックアップ性能が大幅に低下することがあります。Windows Server 2016,

脅威検出 悪意のある操作や不正な動作を継続的にモニタリングす る脅威検出サービスを導入しています。アカウント侵害の

この P 1 P 2 を抵抗板の動きにより測定し、その動きをマグネットを通して指針の動きにし、流

性能  機能確認  容量確認  容量及び所定の動作について確 認する。 .

性能  機能確認  容量確認  容量及び所定の動作について確 認する。 .