• ベストアンサー

recv関数の受信結果について

send関数で送信、recv関数で受信をPG内で繰り返してます。 (MAIL、RCPT等) この時、recv関た数が受け取るメッセージは内部ではどうなって いるのでしょうか? 1.実行分だけたまる 2.最後の実行が上書きされる。 1の場合、どこかでそのエリアをクリアしないとメモリリークが 起きるのかな?と心配があります。 もし、1であればエリアをクリアする方法をご教授頂ければ と思います。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.4

>>内部の領域は"250 OK220 OK\0"となるのでしょうか? 通常、socket通信は、送信するバイト列をバイナリとしてそのまま送信するので、'\0'を最後に送信していれば、上記のようになるでしょうし、送ってなければ、'\0'は届かないですね。Cの文字列のような'\0'が文字列の終わりのような役割は無いです。もしそうであれば、intやlongのデータをそのままでは送れないことになってしまいます。 そして通常は構造体を丸ごと送信するケースが多いようです。 ただ、「そのまま送る」といっても、例えば100bytesを1回でsendしたとき、「100bytesのパケットが飛ぶ」とは限りません。100bytesを1回でrecvしたり、50bytesが2回、またちょっと考えにくいのですが、1byteを100回recvするということになるかもしれません。 socketはパケットというよりも、「ダラダラと続くバイト列が適当に切られてrecvされる」と考えたほうがいいと思います。 >>ここで220から読むには読み捨てが必要になるのでしょうか? ネットワークのエラー等で再送されたデータなど、ほんとにいらないデータなら読み捨てですが、処理に必要なデータなら処理します。通常は、先頭に長さデータの情報を付加したり、データ内に出現しないコードを区切り文字として、受信したバイト列を、送信時のパケットあるいは1レコードとして復元させます。たとえば、"250 OK220 OK"のデータなら、基本的に6バイト読んで1レコードという処理を2回することになります。 実際の処理では、通信経路上のノイズや処理遅延などでデータ欠落が発生したりするため、シーケンスNoなどで、受信したレコードが正しいか確認する処理を行います。 注:実際には、ネットに流すデータはバイトオーダも考慮してください。

derby
質問者

お礼

ありがとうございます。 もうすぐ単体試験が始まるので、不具合が出た際は 参考にしたいと思います。

その他の回答 (3)

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.3

OS側でrecv()でメモリリークが起きるかどうかはOSの問題です。 いづれにせよ、このような単純なメモリ管理方式はとっていません。 >1.実行分だけたまる >2.最後の実行が上書きされる。 少なくとも、UNIX系OSに関しては、recv/sendなどソケット系システムコールでメモリリークは起こりません。 というか、「OS内部でどうメモリを使っているかアプリケーションプログラマが考えて、メモリリークを起こさないように気をつけてプログラミングする」というのはWindowsなど腐れたOSの話です。ソケットAPIではそのような制約はありません。受け取ったパケットをrecvで取り出さなければある程度までメモリ消費量が膨らみますが、いずれにせよcloseした時点ですべて元に戻ります。

derby
質問者

お礼

ありがとうございます。 メモリに関して心配なさそうですね。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.2

send,recv関数で行うソケット通信は、OSで送受信用バッファが用意されます。これに余裕がある間は、送信受信が行われますが、一杯になれば、バッファに空きができるまで停止します。また、ネットワークにデータを流す送受信の単位は、TCPパケットの送受信の最適化をするため、1バイトずつ送ったとしても、受信側に1バイト単位で届くということはないようです。 それから、受信分が貯まった場合の問題は、空きが無くなるメモリーパンク状態で、メモリーリークではないですね。 もし、ゴミデータだと判別できるなら、読み捨てをやればいいと思いますし、この処理が必要なケースはよくあると思います。

derby
質問者

補足

やはり読み捨てでしょうか? 例えば、 1回目が「250 OK」で2回目が「220 OK」だとして、 内部の領域は"250 OK220 OK\0"となるのでしょうか? recvで最初に3バイト取得すると、次は250のスペースからに なりますか? ここで220から読むには読み捨てが必要になるのでしょうか? よろしくお願いします。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.1

言語は何でしょうか? Cだったら、recvがつかうデータエリアは呼び出し側が用意して渡すので、メモリリークが起きるかおきないかはrecvをつかうプログラムしだいです。

derby
質問者

補足

ありがとうございます。 言語はCです。 recvでの応答メッセージの先頭3バイトだけでいいので、 3バイト分用意して、取得しています。 読み捨てる分は影響なしと考えていいでしょうか?

関連するQ&A