windows XP - Linux(FC4) 間でソケット通信プログラムを書いています。

windows側をクライアントとしてwinsock1.0で実装、Linux側がサーバーです。

今、windows側からsend関数で画像データを送信します。画像データのサイズが100MB程度以下なら、全く問題なく送信できるのですが、それ以上のデータになるとsend()の返り値が-1になってしまいます。。。

windows、Linux、それぞれのOS側になにか制限があるのではないかと考えているのですが、どなたか原因をおしえていただけないでしょうか。

回答の条件
  • 1人2回まで
  • 登録:2007/09/07 08:09:30
  • 終了:2007/09/14 08:10:02

回答(2件)

id:KUROX No.1

KUROX回答回数3542ベストアンサー獲得回数1402007/09/07 08:46:36

ポイント35pt

http://www.geekpage.jp/programming/winsock/wsagetlasterror.php

上記ようなコードを組み込んで、エラー内容を取得してはどう

でしょうか?

WinSock2.0でしか使えない機能のようですが、、

もしそうなら、WinSock2.0で簡単なソースを書いて、

エラーになるかどうか、エラーになった場合は、エラーコード

を取得して原因を調べるのが良いと思います。

winsock1.0でも、lasterrorぐらいは分かりそうですが、

ちょっと見つかりません。

id:doubleA

失礼しました。

エラーコードは10057で、意味は

「ソケットが接続されていないか、sendto 呼び出しを使ってデータグラム ソケットで送信するときにアドレスが指定されていないため、データの送受信を要求することは禁じられています。」

だそうです。

2007/09/07 09:22:16
id:ardarim No.2

ardarim回答回数892ベストアンサー獲得回数1422007/09/08 01:23:54

ポイント35pt

下記のいずれかの原因と推測します。

  • send()の制限
  • Winsockの制限
  • 使用しているLANドライバの制限

おそらくどれかがある一定のサイズ以上送れない様なつくりになっているのでしょう。


どちらにせよあまり大量に送るのは危険なのでより小さい単位で何回かに分けてsend()すればよいのではないでしょうか?

ご存知とは思いますが、ソケット通信ではデータの切れ目は意識できませんのでsend()を小分けにして送ろうが、1回のsend()でまとめて送ろうが、recv()側での見え方(処理)は変わりません。

id:doubleA

ardarimさん。

回答ありがとうございます。私もardarimさんが指摘されている3つの要因(LANドライバの制限については考えていませんでしたね、、、ご指摘ありがとうございます)についていろいろ調べているのですが、探し方が悪いのか、データサイズの制限に関する記述がみつからないのです。。。

できれば、ソースを提示していただけないでしょうか?

2007/09/10 11:12:26
  • id:KUROX
    とりあえず10M単位に切って送るとかでは駄目なんでしょうか?
    結局エラーなら再送処理をいれないと駄目ですしね。

    原因は分からないまま進むので良くはないでしょうが・・・。
  • id:doubleA
    期日までに間に合わなければ、その小分け作戦で行こうと思っていますが。。。
    ちょっと気持ち悪いですね。ひょっとしたら、私のプログラムがなんかおかしいのかもしれませんし。
  • id:ardarim
    すみません、上の回答ですが特にソースのようなものはなく、自身の経験則によるものです。
    経験則といっても、Windowsのネットワークスタックについてはそこそこの知識はあると思っていますので全くの見当違いということはないと思ってます。

    そもそもsend()の完了は、ネットワーク上に全てのパケットが送出されたことを意味しません。send()は、Winsock内のバッファに転送するだけで、そこから先はTCPスタックにより非同期にLANドライバへの送出が行われます。send()の動作については下記を参照。
    http://support.microsoft.com/kb/214397/ja

    したがって、send()の失敗は送出自体の失敗であり、受け側(Linux)の問題の可能性はきわめて低いです。(LAN上にデータが載る前のエラー)
    更に言ってしまえば、(仕様が公開されていない)Winsockの内部バッファサイズの限界だと思います。

    上のurlより、
    -----------------------------------------------
    Winsock では、必要に応じて SO_SNDBUF で指定されたバッファ サイズよりもはるかに大きなデータをバッファリングできます。多くの場合、アプリケーションでの送信完了は、アプリケーション送信呼び出しのデータ バッファが Winsock カーネル バッファにコピーされたことだけを示し、実際にデータがネットワーク メディアに送り出されたかどうかは示しません。唯一の例外は、SO_SNDBUF を 0 に設定して Winsock バッファリングを無効にしたときです。
    -----------------------------------------------
    SO_SNDBUFを0にするとWinsockバッファリングが無効になるようなのでもしかしたらうまくいくかもしれません。逆にバッファリングされないので最大SO_MAX_MSG_SIZEまでのメッセージしか送れなくなるだけかもしれません。(試してはいないので不明)
  • id:doubleA
    ardarim さん。丁寧な回答ありがとうございます。
    通信以外の部分のデバッグに追われて、返信遅れました。

    SO_SNDBUF=0の件、試してみたいと思います。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません