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

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

ただいまの
回答率

90.47%

  • TCP

    167questions

    TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

  • Visual C++

    115questions

    Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

TCPでのビットマップの送信

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,581

cfu0987_APV

score 9

TCP通信について勉強し始めて日が浅い者です。
数値とビットマップ画像をTCPで送るプログラムを作成しています。
数値は正常に受け取り表示ができました。
しかし、ビットマップについては小さな画像(200kバイト)はなんとか送受信できたのですが、
大きな画像(1M以上)を送ろうとすると、ビルドは完了できますがソフトの起動ができません。
デバックで実行した場合はStack overflowと表示されるため、(A)が問題だと思いますが他の方法が思いつきません。どなたかうまく送れる方法をご教示ください。

〇環境
  OS:windouws7(SP1) 32ビットOS
   開発:visual C++(2008)
 メモリ:4GB
   CPU:2.5GHz

〇プログラム
★struct.h:

#define MAX_BMP_SIZE    500000//・・・1M以上を送る場合はここを10000000以上にしています。(A)
 typedef struct {
  unsigned short    marker;//①マーカー
  unsigned long    size;//②データバイト数
  unsigned short tp;//③ヘッダ種別
  unsigned short  no;//④ヘッダ番号
  float        x;//数値1
  float        y;//数値2
  unsigned char    bmpfile[MAX_BMP_SIZE];//ビットマップ用の配列
 } BMP_PIC;

★tTCP.h:

Class CtTCP:public CDialog
 {
  ・・・・ 
  public:
   BMP_PIC m_BmpPic;
 };

★tTCP.cpp:

FILE *BMPFP;
 #define BMPDATA  ".\\pic.bmp"
 void CtTCP::Loop(void)
 {
 ・・・・
 M_TAB = 0;
  if(M_TAB == 0){
   BMPFP = fopen(BMPDATA, "rb");

   m_BmpPic.marker = 0xABCD;
   m_BmpPic.size = sizeof(BMP_PIC) - 10;//・・・実際のデータ(数値+ビットマップ)サイズを指定する。
   m_BmpPic.type = 0;
   m_BmpPic.no = 0;
   m_BmpPic.x = 1000;
   m_BmpPic.y = 2000;
   fread(m_BmpPic.bmpfile, 1, sizeof(BMP_PIC), BMPFP);
   sendsize = send(s1, reinterpret_cast<const char*>(&m_BmpPic), sizeof(m_BmpPic), 0);
   //↑のs1はソケットです。

   fclose(BMPFP);
   M_TAB = 1;
  }
 }

*ちなみに上のプログラムの場合、送り側で200kのビットマップが受信側では500k近いサイズになっています。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • suzukis

    2016/04/17 16:09

    コードの部分は前後の行を```(バッククオート3つ)で囲むと見やすくなります。コードの部分を選択してエディタで"</>"のボタンを押してもいいです。

    キャンセル

  • cfu0987_APV

    2016/04/17 18:16

    ご指摘ありがとうございます。 コードを見やすくしました。

    キャンセル

回答 2

checkベストアンサー

+1

こんにちは。

ご提示されたソースの範囲では分かりませんが、 CtTCPのインスタンスをスタック上に確保しているのではないでしょうか?
確かスタックのサイズはデフォルトで1MBytesでしたので、これを越えるサイズの領域をスタック上に確保しようとしてスタックオーバーフローが発生しているものと思われます。

CtTCPのインスタンスをスタックではなくヒープ上に確保(newで生成)することをお勧めします。
リークが怖い時は、C++11で使えるstd::unique_ptrを使えばリークしません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/19 20:59

    ヒープ上に確保した結果、1M以上のファイルの送信に成功しました。
    ありがとうございました。

    キャンセル

0

BMP_PICが固定サイズなので、画像サイズ問わず「ヘッダ類(BMP_PICbmpfile以外のメンバ)+MAX_BMP_SIZE`」のサイズのデータが送信されるプログラムになっています。

  • sizeはファイルサイズから正しく取得する
  • bmpfileには送信側ではデータを入れない。
  • 画像データそのものは、もっと小さい固定長のバッファ(64KBとか128KBとか)に逐次読み込みつつ送信する。データサイズがあまり巨大でなくメモリに余裕があること前提なら、固定長ではなくファイルサイズ分のメモリを確保して一度に読み込み/送信してもよい

とする方がよいと思います。

分割して逐次送信は面倒くさいと思うかもしれませんが、受信側ではどうせやらないといけないことなのですから、方法は理解しておく必要があります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/04/19 21:04

    ご指摘ありがとうございました。
    ゆくゆくはファイルサイズ分のみを送るよう考えコードを修正していますが、また問題点が出てきました。質問を'https://teratail.com/questions/32780'にしましたので、もしよろしければコメントをお願いいたします。

    キャンセル

関連した質問

  • 解決済

    C言語とC#間でSocket通信をさせたい

    前提・実現したいこと C言語とC#でローカルな(同一PC内での)ソケット通信を行いたいです。 C言語側ではWinSocketを利用してサーバーを立て C#側ではSystem.

  • 解決済

    visual studio 2015での型のサイズに関して

    他の方の質問(https://teratail.com/questions/54072)で解決済みになっているのですが、まだ理解できない部分があったので似たような質問になりますが再

  • 解決済

    c言語での音声データの読み込み

    音声データのrawファイルをcのプログラムで読み込み、引数で与えた開始と終了時間の音声波形をgnuplotかexcelで表示したいのですが、rawファイルをどう読み込めばいいのか、

  • 受付中

    C:大きな数の計算方法,オーバーフロー回避

    C言語で3^80の計算をしたいのですが、数が大きすぎてオーバーフローしてしまいます。各桁ごとに配列を置けばいいのかとも思いましたが、いまいちよくわかりません。 解決方法が分かる方

  • 解決済

    ビットの回転について

    前提 現在書籍でc言語を学習している者です。 その書籍の演習問題は解答が存在しておらず(著者の意図的に) 学習を進めることが困難な時があるので、問題のヒント等を教えていただきたいで

  • 解決済

    ファイルディスクリプタのメモリ使用量の考え方について

    概要 Squidのファイルディスクリプタ(FD)を増やすにあたり、 そもそもFDがどれだけメモリを使用するか気になりました。 自分なりに調査をしましたが結論が出ませんでした。 知見

  • 解決済

    gcry_mpi_t 内の公開鍵をビット列で取り出したい

     gcry_mpi_t 内の公開鍵をビット列で取り出したい libgcrypt1.7.6 を使ってRSA暗号をいじってく中で, gcry_mpi_t型におさまっている公開鍵をビット

  • 解決済

    sizeof()のキャストについてのアンチパターン

    qiitaの記事を読んでC言語のプログラミングでのアンチパターンを学習しているのですが、 void func() { int loop = 0; struct aaa

同じタグがついた質問を見る

  • TCP

    167questions

    TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

  • Visual C++

    115questions

    Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。