質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

1694閲覧

C/C++ read. write

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/03/03 09:48

前提・実現したいこと

"www.yahoo.co.jp"からTCP/IPを使用してHTTPソケットからHTMLコードをコンソールに表示したいです。
該当ソースコードをコンパイル・実行して頂けると分かるのですが、正しく動作します。
しかし、個人的に疑問があるのでどなたかご教授頂けると幸いです。

発生している問題・エラーメッセージ

該当ソースコードにおける

c++

1sprintf(buf, "GET %s\r\n", filename); 2write(1, buf, strlen(buf)); 3write(s, buf, strlen(buf)); 4 5while (1) { 6 code = read(s, buf, sizeof(buf)); 7 if(code <= 0) break; 8 write(1, buf, code); 9}

の部分ですが、いまいち理解が出来ません。
凄く簡潔に話すなら、yahooサーバとソケットを用いて通信経路を確率した後に、
sizeof(buffer)分読み込んでwriteで標準出力すれば良いと思っています。
その場合、個人的には、以下のコードのみで実行出来て欲しいのですが、上手く動作してくれません。

c++

1while(true){ 2 code = read(s, buffer, sizeof(buffer)); 3 if(code <= 0){ break; } 4 write(1, buffer, code); 5}

以下の部分が必要な理由を分かりやすく教えて頂けると幸いです。
よろしくお願いします。

c++

1sprintf(buf, "GET %s\r\n", filename); 2write(1, buf, strlen(buf)); 3write(s, buf, strlen(buf));

該当のソースコード

c++

1#include <iostream> 2#include <netdb.h> 3#include <netinet/in.h> 4#include <strings.h> 5#include <sys/socket.h> 6#include <string.h> 7#include <unistd.h> 8 9#include <stdio.h> 10 11#include <errno.h> 12 13using namespace std; 14 15#define HTTP (u_short)80 16 17int main() 18{ 19 /* gethostbyname */ 20 const char *hostname = "www.yahoo.co.jp"; 21 struct hostent *hostent; 22 23 hostent = gethostbyname(hostname); 24 /* gethostbyname */ 25 26 /* sockaddr_in */ 27 struct sockaddr_in sockaddr_in; 28 29 bzero((char*)&sockaddr_in, sizeof(sockaddr_in)); 30 31 sockaddr_in.sin_family = AF_INET; 32 sockaddr_in.sin_port = htons(HTTP); 33 34 bcopy(hostent->h_addr_list[0], (char*)&sockaddr_in.sin_addr, hostent->h_length); 35 /* sockaddr_in */ 36 37 /* socket */ 38 int s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 39 40 int code = connect(s, (struct sockaddr*)&sockaddr_in, sizeof(sockaddr_in)); 41 42 char buffer[5000]; 43 44 sprintf(buf, "GET %s\r\n", filename); 45 write(1, buf, strlen(buf)); 46 write(s, buf, strlen(buf)); 47 48 while (1) { 49 code = read(s, buf, sizeof(buf)); 50 if(code <= 0) break; 51 write(1, buf, code); 52 } 53 54 close(s); 55 /* socket */ 56 57 /* errno */ 58 cout<<"errno: "<<strerror(errno)<<endl; 59 /* errno */ 60 61 62 63 return 0; 64}

試したこと

以下コードをコメントアウトしたりして、一行ずつ実行したりしてみた。
また、サイトを参照したりした。
参照サイト1
参照サイト2

c++

1sprintf(buf, "GET %s\r\n", filename); 2write(1, buf, strlen(buf)); 3write(s, buf, strlen(buf)); 4 5while (1) { 6 code = read(s, buf, sizeof(buf)); 7 if(code <= 0) break; 8 write(1, buf, code); 9}

補足情報

WSL(Windows Subsystem for Linux)
g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

HTTPプロトコルについて解説せずに、この課題をやらせるのであれば、欠陥テキストですね。
見落としてじゃないでしょうか?テキストの前の部分で、HTTPプロトコルについての解説ページがおそらくあると思います。もしくは、そのあたりは必須前提知識なのかも。

投稿2020/03/03 12:58

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TsukubaDepot

2020/03/03 13:16

私だったら、まず自前(教育機関?)のサーバに telnet で接続させて試させますね。 自前のサーバならまだしも、赤の他人のサーバにプロトコルも守らないで接続させるのは、いまどきちょっとアレな気がします。
otn

2020/03/03 13:23

ウェブ上の入門記事じゃなくて、教育機関?? だとすると、問題ですね。 (ウェブ上の入門記事だと問題ないという意味じゃなくて、ウェブ上の入門記事だと玉石混交なので、言ってもしょうがないという意味です)
TsukubaDepot

2020/03/03 13:56

あ、教育機関というのは私の勝手な想像です。 昨日もほとんど同じコードを見た覚えがあるので、どこかの課題かな?と思って調べ直したら同じ方の質問でした。
guest

0

サーバの反応について凄く簡潔に話すなら、「何も言わずに訪ねてきた人(プログラム)には何もあげない」ということです。
サーバから何を得たいのか、自分の得体はなんなのか、そういうことを相手(サーバ)に伝える必要があります。その一つが「GET」というメソッドだったりするわけです。

HTTPやメールをはじめ、多くの通信技術というのは「プロトコル」という規約に従って情報を交換します。

「通信プロトコル」とか、「HTTP プロトコル」とかいうキーワードで調べてみると色々出てくると思います。


昨日から同じソースコードで質問してくる人がいますけど、課題なのですかね?

投稿2020/03/03 10:50

編集2020/03/03 13:14
TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

コメントを入れるとこんな感じでしょうか

// buf に"GET (filename)^r\n" を書き込む sprintf(buf, "GET %s\r\n", filename); // 標準出力に "GET (filename)^r\n" を出力する write(1, buf, strlen(buf)); // s(ソケット、www.yahoo.com のサーバ) に"GET (filename)^r\n" を出力する write(s, buf, strlen(buf));

http は"GET xxx" というコマンドを送ってやらないと、何も返事をしてくれないので、それを送信する必要があります

投稿2020/03/03 10:26

izmktr

総合スコア2856

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問