[C++] 155 TCP/IP HTTPプロトコル

[M1 Mac, Big Sur 11.6.8, clang 13.0.0, NO IDE]

昨年2021年7月に購入した『C言語によるTCP/IPネットワークプログラミング』(初版 2001年)をようやく読み始めました。

まずはHTTPプロトコルのサンプルコードを走らせようとしましたが、何せ21年前に書かれたC99のコードなので案の定エラーの嵐でした。

色々修正し、さらにC言語をC++に変えて完成させました。

修正手順
1.ヘッダファイルを別途作成
2.”exit(-1)”を”return -1″に書き換え他
3.va_listまわりの修正
4.Makefileの書き換え(ccコンパイラをclang++へ変更他)

一番苦労したのは変数引数リストva_listを作成するところです。元ソースにあったvarargs.hがすでに廃止されていたため、stdarg.hに切り替えました。引数の内容が変わっており、修正に結構時間を費やしました。

Mac mini内にMAMPで仮想Webサーバーを立ち上げ、その中にあるindex.htmlにアクセスしてみました。

とりあえず動きましたが、コードの内容についてはこれから理解を深めていきます。

# コマンド
httpget localhost:/index.html
--------------------------------------------------
出力
--------------------------------------------------
host=localhost,path=/index.html
GET /index.html HTTP/1.0

HTTP/1.1 200 OK
Date: Tue, 23 Aug 2022 16:06:37 GMT
Server: Apache/2.4.46 (Unix) OpenSSL/1.0.2u PHP/7.4.21 mod_wsgi/3.5 Python/2.7.18 mod_fastcgi/mod_fastcgi-SNAP-0910052141 mod_perl/2.0.11 Perl/v5.30.1
Last-Modified: Tue, 23 Aug 2022 16:04:38 GMT
ETag: "78-5e6eab8a35180"
Accept-Ranges: bytes
Content-Length: 120
Connection: close
Content-Type: text/html
int main(int argc,char *argv[])
{
char buf[512];
char host[MAXHOSTNAMELEN],path[512],*ptr;
int	i;

	if(argc<=1){
		fprintf(stderr,"httpget host:path ...\n");
		// exit(-1);
		return -1;
	}

	// 引数のループ 
	for(i=1;i<argc;i++){
		// ホスト:パス 
		strcpy(buf,argv[i]);
		if((ptr=strtok(buf,":"))==NULL){
			strcpy(host,"localhost");
			strcpy(path,argv[1]);
		}
		else{
			strcpy(host,ptr);
			if((ptr=strtok(NULL,""))==NULL){
				fprintf(stderr,"host:path error\n");
				// exit(-1);
				return -1;
			}
			strcpy(path,ptr);
		}
		// HTTP取得実行 
		DoHttpGet(host,path);
	}
}

int SOCprintf(int num, ...)
// va_dcl
{
	va_list args;
	int	soc;
	char *fmt;
	char buf[4096];

	va_start(args,num);
	soc = va_arg(args,int);
	fmt = va_arg(args,char *);

	vsprintf(buf,fmt,args);
	vfprintf(stderr,fmt,args);
	va_end(args);

	send(soc,buf,strlen(buf),0);

	return 0;
}