teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

脱字修正

2020/08/12 19:07

投稿

dodox86
dodox86

スコア9416

answer CHANGED
@@ -1,4 +1,4 @@
1
- 質問者lushimoさんの[2020/08/13 00:22]より引用:
1
+ 質問への追記・修正欄」における質問者lushimoさんの[2020/08/13 00:22]のコメントより引用:
2
2
 
3
3
  > 1.recvの第2引数のresultにメモリを確保していないことが原因だったのでしたら、その状態でも第三引数が35であればデータの受け取りができたのは何故でしょうか?
4
4
 
@@ -7,13 +7,13 @@
7
7
  > 2.resultに確保すべきメモリはいくつ必要になりますか?
8
8
  > ポインタ変数なので4でいいのか、それとも返ってくるファイルの内容のサイズ分確保すべきなのでしょうか?試してみたところ4でも3000でも1でも0でもデータの受け取りができておりますので、
9
9
 
10
- 確保すべきサイズは「1回の`recv()`実行で受信するデータの最大のサイズ」です。例えばもし最終的に受信したいデータの総サイズが1万バイトだったとしても、小分けに10バイトづつ受信するのであれば`recv()`に渡すバッファのサイズは10バイトで構いません。プログラマーが責任をもってその小分けされたデータを連結します。言い方を変えるとその前後のプログラミング次第です。
10
+ 確保すべきサイズは「1回の`recv()`実行で受信可能とするデータの最大のサイズ」です。例えばもし最終的に受信したいデータの総サイズが1万バイトだったとしても、小分けに10バイトづつ受信するのであれば`recv()`に渡すバッファのサイズは10バイトで構いません。プログラマーが責任をもってその小分けされたデータを連結します。言い方を変えるとその前後のプログラミング次第です。
11
11
 
12
12
  ソケットプログラミング、特にTCPの前提として、相手側(質問者さんの場合はサーバー)が1回の`send()`で1万バイトを送っても、1回の`recv()`で1万バイト受信できるとは限りません。場合によっては1000バイトづつ小分けにされて受信する場合もありますし、そうなることを見越してコードを書く必要があります。サーバー側で合計何バイト送ってくるか分からない場合は、そのデータの中にデータの末端を示すマークを含めて送るとか、データ長自体を示すデータを含めます。TCPの代表的なHTTPでも、サーバーからクライアントに送られてくるHTTPレスポンスにはデータの末端を示す2つの連続する空行(`"\r\n\r\n"`)であるとか、データ部の長さを示す`"Content-Length: 1234\r\n"`のようなヘッダーフィールドがあります。クライアント側はそれらを適時判断して、受信すべき総データ長を決めることになります。それは質問者さんのコードでも同様です。
13
13
 
14
14
  尚、ソケットプログラミングのレベルでいえば`recv`の返り値に`0`が返ってきたときはコネクションが切断されたことを示します。それ以降データは受信できないので、それをもって終了とする場合もあります。ソケットプログラミングのサンプルコードでもそのようなコードになっていることが多いので、気を付けて確認してみてください。
15
15
 
16
- 上記をある程度踏まえて質問者さんのコードを修正してみたのが以下のコードです。コメントの`NOTE:`部分にも注意して読んでみてください。(私の方ではMinGWではなく、Visual Studio 2019 で確認しています)
16
+ 上記をある程度踏まえて質問者さんのコードを修正してみたのが以下のコードです。コメントの`NOTE:`部分にも注意して読んでみてください。(私の方ではMinGW/gccではなく、Visual Studio 2019 で確認しています)
17
17
  ```C
18
18
  #include <stdio.h>
19
19
  #include <WinSock2.h>