【先着1,000名様!】1,000円分をプレゼント!

こんにちは。
現在、クライアント&サーバの通信プログラムを作成しています。
クライアントがサーバに接続しにいく際、サーバの待ち受けポートにクライアントが
UDPでブロードキャストしています。
その際、クライアントの情報もUDPに乗せて、送信しています。

ここで、問題なのですが、ネットワークモニタで通信データを見てみると、
クライアントから送信するUDPデータが1500バイト?を超えると、UDPパケットの分割が行われ、
2つめのデータが、UDPではなく、IPで送信されています。

しかも、2つめのIPのパケットがサーバ側に届くケースと届かないケースがあるように見受けられます。
(環境の違いかもしれません。)
2つめのパケット破棄は破棄が起こる環境では必ず起きます。
破棄が起きない環境では一回も起こりません。

スイッチ、NIC等で、破棄することってあるのでしょうか?
ネットワーク上の問題っぽいので、OSの違い(Win2K pro,Win2k advanced server)
などには関係ないですよね?

どなたが、ご存知の方がおられましたらご教授願います。

このQ&Aに関連する最新のQ&A

A 回答 (3件)

Ethernetのフレームサイズの上限が1500バイトなのはご存知ですか?



IP自体は1500バイト以上送れますが,例えば途中の経路にEthernetがあった場合,送信時にエラーとなるか、
複数のIPに分割して送信するかします(OSやプログラム、ドライバ等の設定による)。
分割した場合は、UDPの前の方が含まれるIPパケットと
UDPの後ろの方が含まれるIPパケットになります。
つまり、質問されているようなUDPとIPに分かれたように見えてるものは、単にUDPの前の方が含まれるIPパケットと
残りが含まれるIPパケットというだけで、
それそのものは問題ありません。
あとは、受信した側でその二つのIPパケットからUDPを復元するだけです。
これでIPからすれば、分割されずに1パケットとして通信されたように見えます。

話からすると、途中のスイッチなりルータなりFWなりか、受信側のIPドライバ(?)が分割されたIPパケットを正しく処理できてないか,
そもそもIPパケットの分割に対応していないのではないかと思います。

ちなみに、WindowsはIPパケット分割不可の設定で送信するらしいので、このようなデータは送信時にエラーになると思います。
ただ、エラー自体は送信時でなく送信後に発生することになると思いますので,プログラムで検出できるかどうかはわかりませんが。

UDPを使うなら分割が起きないよう,1パケットのサイズは途中経路のフレームなりパケットのサイズを越えないようにした方がいいように思いますが。
そうじゃないと、このケースだとエラー出る経路上の全てをチェックし、必要なら機器なりソフトなりを交換しないとだめなように思えます。

私が作る場合,状況によってはTCPでもEthernetの1フレームに収まるようにしますし、
UDPならまず間違い無く1500(IP,UDPヘッダサイズ込み)以下にします。
もちろん、足らない場合はありますが、その場合はプログラムで自分用のヘッダつけて対処します。

パケットをモニタできるなら、ICMPのエラーが帰ってきているかも知れませんのでチェックしてみてください。
    • good
    • 1

IPパケットがネットワークの途中で消えることがあるかということなら、ありますね。


消えることがあるからこそ、確実に通信を行うためのTCPがあり、IPより上位層で連番管理や受信応答を行い、不着や抜けを検知すると自動再送することで、確実な通信を実現しているわけです。
そういうことを行わないのがUDPなので、届いた・届かないなどの管理はプログラマが行わなければなりません。
消える原因として考えられるのは、
・他のパケットとの衝突
・ノイズ
・接触不良
・電圧変動や高温によるネット機器の不安定動作
などで、IPパケットのデータがビット化けを起こし、チェックサムエラーとなればNIC、スイッチ、ルーター等でパケットが廃棄されます。

再現性があるなら環境の違いを詳しく調べると何か原因がわかるかもしれません。交換できるものは交換してみて変化を見るとか。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
やはり、UDPの限界(システムで使用する)というものがあるという感じでしょうか。
今回のようなシステムでは、TCPを使用するほうがよりベターであるということですよね?

ありがとうございました。

お礼日時:2004/06/15 12:52

UDPは到達が必ずしも保証されないものだと聞いたことがあります。

リアルタイムのストリーミングなどで使われているようです
    • good
    • 0
この回答へのお礼

早速のご回答ありがとうございます。
確かにUDPは到達が保障されないプロトコルだということは知っているのですが、
必ずしも、届かないという現象の原因はなんなのか?ということを調査しています。

お礼日時:2004/06/12 14:51

このQ&Aに関連する人気のQ&A

UDP とは」に関するQ&A: NTP の TCPポートは?

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QUDP通信する時に、相手にどうやって自分のポート番号を教える?

UDP通信する時に、相手(送信側)にどうやって自分(受信側)のポート番号を教えるのでしょうか?

例えば、下記のページのサンプルだと、受信側は5555で待ち受けていますが、この場合は送信側はあらかじめ受信側が5555で待ち受けていると知っています。送信側が知らない場合に、どうやって受信側のポート番号を知らせればよいのでしょうか?

http://www.hellohiro.com/datagram.htm

Aベストアンサー

#1です。

> 受信側は
> DatagramSocket
> を引数なしでインスタンス化して、receiveメソッドを動かせば、そこに返ってくる、ということなのでしょうか?

「返ってくる」というのはレスポンスのことでしょうか。その前提で話をします。

最初の回答のA→B(リクエスト)とB→A(レスポンス)のうち,Aがこの質問のとおりに動作するには,Bが以下のような動作を行う必要があります。逆にBが以下のような動作をするならAの動作はご質問のとおりです。

1)Aは引数なし,Bは固定のポートを指定してインスタンス化。
2)Aは送信するリクエストパケット(DatagramPacket)を作り,これにBのIPアドレスとポートをセットして送信。
3)BのIPアドレス・ポートにAからのパケット到着。Bはこれをreceiveメソッドで受け取る。
4)BはAからのパケットに含まれるAのIPアドレスとポート番号を取得する(DatagramPacketのgetSocketAddressメソッドで多分取得可)。
5)Bはレスポンスを作成し,取得したAのIPアドレスとポートをレスポンスパケット(DatagramPacket)にセットしてこれを送信。
6)AのIPアドレス・ポートにBからのパケット到着。Aはこれをreceiveメソッドで受け取る。

UDPでは,リクエストを送って相手がそれを受け取れば,UDP通信はそれでおわりです。リクエストに対してレスポンスを返す場合,送信側と受信側が入れ替わって新規のUDP通信を始めることになります。

#1です。

> 受信側は
> DatagramSocket
> を引数なしでインスタンス化して、receiveメソッドを動かせば、そこに返ってくる、ということなのでしょうか?

「返ってくる」というのはレスポンスのことでしょうか。その前提で話をします。

最初の回答のA→B(リクエスト)とB→A(レスポンス)のうち,Aがこの質問のとおりに動作するには,Bが以下のような動作を行う必要があります。逆にBが以下のような動作をするならAの動作はご質問のとおりです。

1)Aは引数なし,Bは固定のポートを指定し...続きを読む

Qパケットロスと遅延について

(1)パケットロスって何でしょうか?
(2)パケットロスが10%でも、回線品質は良くないのでしょうか?WAN間でも必ずパケットロスは0%でないと品質は良いとは言えないのでしょうか?
(3)パケットロスが発生しても、データは遅くても完全に届くものでしょうか?それともパケットロス分のみ捨てられて、相手に届くのでしょうか?
(4)パケットロスが発生すると、遅延も必ず起きているのでしょうか?
(5)パケットロスと遅延がネットワーク側に問題があると判明した場合、どのような措置を講ずるのでしょうか?
(6)TCPパケットはパケットロスがあると再送しますが、UDPパケットは再送しないで破棄されるのでしょうか?

以上、ネットワークに精通されておる方、お願い申し上げます。

Aベストアンサー

> (1)パケットロスおよび遅延はルータ/SWのMIBからNMSへトラップとして上がってくるのですが、パケットロスおよび遅延はルータ/SWのどの機能で判断しているのでしょうか?

それなりのL2SWはインタフェース(ポート)ごとにトラフィックやパケットロスのカウンタを持っているので、そのカウンタが上がるタイミングでSNMPトラップを出力しているはずです
遅延もSNMPトラップが出ますか?
CiscoのルータはSAA(Service Assurance Agent)という機能があって遅延やジッタをSNMP MIBで見たりできたと思いますが、他のL2SWで遅延を測定/監視できるものは知らないです

> (2)遅延は何msまでが許容範囲とかありますか?

アプリケーションによります
VoIPなどはシビアに効いてきますし、Web参照であれば1秒でもあまり気にならないでしょう
VoIPは遅延だけでなくジッタ(揺らぎ、遅延のばらつき具合)も影響します
ちなみにY.1541は遅延やジッタも定義してますけど、ちゃんとリンク先の情報読みました?

> (3)パケット落ちは、 ping何発中、何発までならOKとかありますでしょうか?

これもアプリケーション次第でしょう
再送の有無や再送にかかる時間とそれがどこまで許容できるか次第かと

> (1)パケットロスおよび遅延はルータ/SWのMIBからNMSへトラップとして上がってくるのですが、パケットロスおよび遅延はルータ/SWのどの機能で判断しているのでしょうか?

それなりのL2SWはインタフェース(ポート)ごとにトラフィックやパケットロスのカウンタを持っているので、そのカウンタが上がるタイミングでSNMPトラップを出力しているはずです
遅延もSNMPトラップが出ますか?
CiscoのルータはSAA(Service Assurance Agent)という機能があって遅延やジッタをSNMP MIBで見たりできたと思いますが、他のL2...続きを読む

QUDPプログラム、データの送受信

javaを使って通信の勉強をしています。

UDPを用いた通信のプログラムを作成しています。
送信側では、次のようにして送信したいバイト数を分割して送信しています。

BUF_MAX = 40960;
DatagramSocket socket = new DatagramSocket();

// data分のバイトデータを分割して送信する。
int part = 5242880 / BUF_MAX; // 分割して送信する回数
send_start = System.nanoTime();
for(int i = 0;i < part;i++){
  byte[] buf = new byte[BUF_MAX];
  buf[0] = (byte)i;
  DatagramPacket sendPacket = new DatagramPacket(buf,BUF_MAX,serverAddress,servPort);
  total += BUF_MAX;
  // 指定したバイト数を送信する。
  try{
    socket.send(sendPacket);
  }catch(IOException e){
    System.out.println(e);
  }
}
System.out.println(total);

このようにしています。
こうする理由は、5242880バイトのデータを128回に分割して送信して、
受信側で受信したパケットの最初の文字を見て、何個目のパケットが届いていないかを確認するためです。

受信側でこれらのデータを受信する方法を考えているのですが、どうすればよいか分かりません。

receive(packet)で受信するのは知っています。
送信された複数のデータを受信するのに、
for(int i = 0;i < 128; i++){
 receive(packet);
}
というようにするのでしょうか?このようにすると、
このループを抜けることができません。それは、パケットが通信途中で紛失するため、128回受信しないからだとおもいます。

受信しなくなったらループを抜けるというようにすればよいとおもいますが、その方法が分かりません。


どなたかアドバイスをいただけないでしょうか?お願いします。

javaを使って通信の勉強をしています。

UDPを用いた通信のプログラムを作成しています。
送信側では、次のようにして送信したいバイト数を分割して送信しています。

BUF_MAX = 40960;
DatagramSocket socket = new DatagramSocket();

// data分のバイトデータを分割して送信する。
int part = 5242880 / BUF_MAX; // 分割して送信する回数
send_start = System.nanoTime();
for(int i = 0;i < part;i++){
  byte[] buf = new byte[BUF_MAX];
  buf[0] = (byte)i;
  DatagramPacket sendPac...続きを読む

Aベストアンサー

案1)時間内に届かなかったらタイムアウトさせる。

案2)届かなかったパケットを再送させるよう、送信元と受信先が双方向にやり取りするようにプログラミングする。

案3)TCPを使う(timeoutは必要)。

QUDP通信におけるbind関数について

初めて質問させていただきます。よろしくお願いします。

最近、ネットワークプログラミングの勉強をしているのですが、bindについてよくわからなくなってきました・・・。よろしければご教授願います。

質問内容は以下の通りです。
(1)bindにおける設定内容は、「相手側のIPとポート番号」なのか「自分側のIPとポート番号」なのか?
 色々なところを調べてみましたが、「IPとポート番号」を設定する、としかかかれてなく、いったいどっちなのかがわからなくなってきました・・・。

(2)UDP通信において、bindは必要なのか?
 サーバ-クライアントの関係が曖昧なUDP通信において、bindというのは必要なのでしょうか。
私の認識では例えば、「recv関数」などを使い受信待ちをする場合はbindが必要だが、送信だけの場合には不要であるとなっています。

この認識はあっているのでしょうか。
拙文ですが、どうか教えていただきたく <(_ _*)>

Aベストアンサー

TCP/UDP通信がどのように働くかを考えれば、疑問の答えが分かるのでは?
bindについて言えば
「OSはマシンに届いたパケットを如何にして該当プログラムに届けるか?」
です。
自分のポート番号をOSに教えてあげなければ、OSは着信したパケットをどのプログラム(プロセス)に届けるか分からないでしょう。それをするのがbindの役割です。
従って(1)は自ポート番号。IPは複数IPを持っているマシンで一部IPでのみ受け付ける場合に必要ですね。
一般的にサーバでbindするタイミングでは相手のIPやポート番号は不明ですから、要求されても困りますね。
(2)は質問者さんの認識通り。受信のために必要、送信では不要です。

QUdpClient 送信元のIPアドレスの指定方法

System.Net.Sockets.UdpClient クラスを使用してのソケット通信を行っています。
プログラムでは、送信元のポート番号のみ引数に渡すだけで
それまで順調に通信は行っていたのですが

//localPort=送信元ポート番号
fUdp = new System.Net.Sockets.UdpClient(localPort);

新たに ネットワークインターフェースカードを追加して、IPアドレスを後から
挿した方に変更してから、通信がうまく動作しなくなってしまいました。

おそらくは、IPアドレスが複数ある為に、うまく動かないのかな?と思い
送信元のポート番号だけでなく、送信元のIPアドレスも合わせて指定してやれば
直ると思い調べていたのですが、送信元IPアドレスの指定する方法が判りません
AddressFamily で指定するのかなとも思ったのですが、ヘルプを見てもよくわからずに
行き詰ってしまいました。

もしよろしければ、送信元のIPアドレスを指定する方法をご教授ねがえませんでしょうか

Aベストアンサー

using System;

using System.Net;

using System.Net.Sockets;

namespace Q6373023

{

public class Q6373023

{

public static void Main(){

UdpClient uc = new UdpClient(new IPEndPoint(IPAddress.Parse("192.168.1.2"),60000)); /* 俺 */

uc.Send(new byte[]{0x01,0x02,0x03},3,new IPEndPoint(IPAddress.Parse("192.168.1.1"),60000)); /* 相手 */

}

}

}

/* こんな感じ?1枚しか刺さってないマシンなので何ともいえないけど。 */

QTCP/IP のパケットの分断と結合について

linux で socket を使ってプログラムを作っております。
パケットの頭に、どんな種類のパケットかの情報を入れ、それに続く部分にデータを入れて送っております。受信側では、届いたパケットの頭の情報を見て必要な処理を行う、という流れになっております。
ところが、時々、次のような現象が発生して困っております。

・送信側で一回のsendで送ったはずのデータが受信側では一回のrecvで届かず、二回のrecvで届く。
・送信側では二回のsendで送ったつもりなのに、受信側では一回のrecvで2つのパケットが結合したデータが届く。

これはsendとrecvでは普通に起こると想定しなければならない現象なのでしょうか?
それとも、linuxマシンの設定に問題があるのでしょうか?

Aベストアンサー

>・送信側で一回のsendで送ったはずのデータが受信側では一回のrecvで届かず、二回のrecvで届く。
>・送信側では二回のsendで送ったつもりなのに、受信側では一回のrecvで2つのパケットが結合したデータが届く。

TCPは「ストリーム」なのでそういう動作をしても不思議ではない。
ということになります。

>それとも、linuxマシンの設定に問題があるのでしょうか?

Windowsでも普通に発生します。

http://www.ne.jp/asahi/hishidama/home/tech/socket/tcp.html
send(送信)、recv(受信)や
http://www.ne.jp/asahi/hishidama/home/tech/socket/index.html#%E9%9B%BB%E6%96%87%E3%81%AE%E7%B5%82%E4%BA%86%E6%A4%9C%E7%9F%A5
等を参照…でしょうか。
# 他にもそういった解説をしているページはあるでしょう。
http://rgv250.dyndns.org/socket.htm

http://hp.vector.co.jp/authors/VA019876/sokrpg/doc/SockFAQ/sfaq01.html
の「たまに、受信したレコードの最後が途中で切れていることがあります。どうしてでしょうか? 」とか…

>・送信側で一回のsendで送ったはずのデータが受信側では一回のrecvで届かず、二回のrecvで届く。
>・送信側では二回のsendで送ったつもりなのに、受信側では一回のrecvで2つのパケットが結合したデータが届く。

TCPは「ストリーム」なのでそういう動作をしても不思議ではない。
ということになります。

>それとも、linuxマシンの設定に問題があるのでしょうか?

Windowsでも普通に発生します。

http://www.ne.jp/asahi/hishidama/home/tech/socket/tcp.html
send(送信)、recv(受信)や
http://www.ne.jp...続きを読む

QUDP通信での受信方法について

MFCでUDPプロトコルを使ったサーバー・クライアントをソケットプログラムで書いております。

ソフトの内容は、クライアントから送信されたの文字列のコマンドをサーバで処理をするだけです。

サーバー側での受信の仕方は
WSAAsyncSelect()関数を使ってソケットイベントが発生するごとに親ウィンドウに自作のメッセージ(WM_MY_MSG)が送られるように設定する



WM_MY_MSGのメッセージハンドラ内でrecvfrom()関数を使って受信する。

という方法を用いています。クライアント2台ぐらいであれば正常に動きます。


質問1:
まだ試したことはないのですが(というより試す環境がない)、ほぼ同時ぐらいに複数(10台ぐらい)のクライアントからコマンドが送信された場合、それを全部正確に受信できるものなのでしょうか?要するに一つのコマンドを処理中に別のコマンドが送られてきた場合の動作はどうなるのでしょうか?

質問2:
UDP通信での受信をする場合の何かもっとスタンダードな方法があるのでしょうか?

よろしくお願いします。

MFCでUDPプロトコルを使ったサーバー・クライアントをソケットプログラムで書いております。

ソフトの内容は、クライアントから送信されたの文字列のコマンドをサーバで処理をするだけです。

サーバー側での受信の仕方は
WSAAsyncSelect()関数を使ってソケットイベントが発生するごとに親ウィンドウに自作のメッセージ(WM_MY_MSG)が送られるように設定する



WM_MY_MSGのメッセージハンドラ内でrecvfrom()関数を使って受信する。

という方法を用いています。クライアント2台ぐらいであれば正常...続きを読む

Aベストアンサー

普段はMFCのSocketではなく
Winsockを使っていますが基本は同じだと思いますので参考までにコメント致します。

質問1:
同時に複数のクライアントからUDPパケットが送信された場合、
データはまず受信側のSocketのキューに格納されます。
なので1つのコマンドを処理中に別の(次の)コマンドを受信しても問題ありません。キューに格納されます。
シーケンシャルにキュー内からコマンドを取り出し終えるまで同じ処理を続ければ良いかと。

質問2:
MFCのSocketは古いVersionのSocketで、
困った記憶があります。v1.1?
(最新情報ではないかもです)
Winsockに関する良い書籍が出てますので
そちらを直接利用されてはどうでしょうか?
http://bookweb.kinokuniya.co.jp/htm/4797306882.html

UDPはコネクションレスですし、難しいことはないと思います。

参考URL:http://bookweb.kinokuniya.co.jp/htm/4797306882.html

普段はMFCのSocketではなく
Winsockを使っていますが基本は同じだと思いますので参考までにコメント致します。

質問1:
同時に複数のクライアントからUDPパケットが送信された場合、
データはまず受信側のSocketのキューに格納されます。
なので1つのコマンドを処理中に別の(次の)コマンドを受信しても問題ありません。キューに格納されます。
シーケンシャルにキュー内からコマンドを取り出し終えるまで同じ処理を続ければ良いかと。

質問2:
MFCのSocketは古いVersionのSocketで、
困った記憶...続きを読む

Qsocket: recvはいつ,どれだけ受け取るのか?

 現在,参考書にしたがってC++でソケットプログラミングを書いています.

 sendとrecvを非同期にするために,本では select関数やWSAAsyncSelect関数などを利用していて,実際,本のとおりに書いて上手く動いています.

 ここで伺いたいのですが,recvは,どうやって「データが届いたか」を知るのでしょうか.

 同期ならば,トランシーバでの会話のように送信側が「どうぞ」といって送受信を交代させることができますが,非同期ならばそれができません.

 NICとかが,プログラムに「届いたぞ!( or これから届くぞ!)」と教えてくれるのでしょうか.あるいは逆に,プログラムがNICに「届いてる?」と聞いているのでしょうか.仮に,ここに書いたような方法で届いたことが分かったとしても,どれくらい受け取ればいいかは分かりません(それも併せて教えてもらっているのでしょうか.データを送るときには,どれだけ送ればいいか分かりますよね.受信するときはどうしてるのかを知りたいと思っています).

Aベストアンサー

Linux しか知らないので Linux で説明をします。

NIC が通信パケットを受け取ると割り込みが発生し、CPU は割り込みを受け付けて、対応するデバイスドライバを起動します。この時、ドライバはソケットバッファと呼ばれる構造体にパケットの中身をコピーして、Linux カーネルの本体に渡し、そこで TCP 等の上位プロトコル処理が行われます。

一方、ユーザプログラムの方は、 select() なり read() で待っている訳ですが、OS はもちろんプロセスが何を待っているかを知っているので、対応する待ちの条件が満たされると、この場合は select() や read() が、抜けてくる(return する)訳です。

という事で、ユーザのプログラムは select() なり read() なりで受信データを「待つ」ことが必要です。もちろん select() や read() が呼ばれた時点で既に受信しているのならば、それらは直ぐに帰ってきます。read() や recv() はデータが届いた事を知る、というよりは、届いているかチェックして、まだ届いていなければ届くまで待つ(read() が抜けてこない)という処理になります。また NIC とユーザプログラムが直接やり取りをするのではなく、間にバッファがあって、対応するソケットのデータがある(受信済み)/ないか(未受信)、という問い合わせを行っているだけです。

ソケットの場合、データの送受信は非同期であり、送受信のタイミングのずれは(ソケット)バッファである程度吸収されます。もちろん、送受信バッファが満杯になった場合は流量制御が働いて、結果的に送信側の write() や send() が待ちに入ることになります。

Linux (Unix) のソケットの受信では、read() 等で指定されたバッファが常に満杯で返されるとは限らない設計になっています。つまり、その時に受信しているデータを返すだけなので、read() で返されたバイト数を必ず見ないと間違った動きになるので注意してください。

Linux しか知らないので Linux で説明をします。

NIC が通信パケットを受け取ると割り込みが発生し、CPU は割り込みを受け付けて、対応するデバイスドライバを起動します。この時、ドライバはソケットバッファと呼ばれる構造体にパケットの中身をコピーして、Linux カーネルの本体に渡し、そこで TCP 等の上位プロトコル処理が行われます。

一方、ユーザプログラムの方は、 select() なり read() で待っている訳ですが、OS はもちろんプロセスが何を待っているかを知っているので、対応する待ちの条件が満...続きを読む

Qunsigned long long 型のフォーマット指定子

unsigned long long 型の変数の値を表示したいのですが、
フォーマット指定子は%ldですか?
よろしくおねがいします。

Aベストアンサー

規格上は、%llu のように ll を付けます。(unsigned long longなので、%lld ではなく %llu です。)
ただし、C99に準拠した処理系ではなく、単に独自拡張としてlong long型をサポートしている場合には、%Lu とか %qu とかになる場合もあります。場合によっては、long long型が存在する処理系でも、printf系関数で正しく書式化する方法が存在しないこともあり得ます。

QTCP/IP通信でのコネクションロスト(ソケットエラー)の検知について

インターネット上での対戦ゲームの作成を行なっているところです。
サーバーを挟んでクライアント間で双方向の通信を行なっています。

 A → サーバー → B
 A ← サーバー ← B

TCP/IPは信頼性の高い通信方法ということで、データ抜けなどは
心配しなくても良いと聞いています。
もし、データ抜けなどが発生した場合はコネクションロストの状態になると。

実際のプログラミングではソケットを使用しています。
コネクションロストが起きると、ソケットエラーかソケットクローズで検知できます。


実際に例えばクライアントAを強制終了させるとサーバーはただちに
ソケットクローズを検知します。


ここで、問題はデータを送っても届かないのに、
ソケットエラーもソケットクローズも起きない状態が発生することです。
これはインターネットの経路上になにか問題が発生したと考えていますが
このような状態はタイムアウトなどで監視する以外に検知する方法はないのでしょうか?


クライアントはウィンドウズでVB6.0のwinsockを、
サーバーはLinuxを使用しています。

なにかアドバイスをいただければありがたいです。

インターネット上での対戦ゲームの作成を行なっているところです。
サーバーを挟んでクライアント間で双方向の通信を行なっています。

 A → サーバー → B
 A ← サーバー ← B

TCP/IPは信頼性の高い通信方法ということで、データ抜けなどは
心配しなくても良いと聞いています。
もし、データ抜けなどが発生した場合はコネクションロストの状態になると。

実際のプログラミングではソケットを使用しています。
コネクションロストが起きると、ソケットエラーかソケットクローズで...続きを読む

Aベストアンサー

>>これはインターネットの経路上になにか問題が発生したと考えていますが
>>このような状態はタイムアウトなどで監視する以外に検知する方法はないのでしょうか?

多くのアプリは、タイムアウトで処理しているようです。例えば、経路途中のどこかのLANケーブルが抜けて通信が失敗した場合、すぐにエラーを検出して異常になるよりも、LANケーブルを差し込んだら、そのまま継続してくれるほうが嬉しいわけですからね。

もし、デフォルトのタイムアウトがいやなら、定期的に信号をやりとりする仕組みを組み込めばいいと思います。ただし、そのやりとり自体もタイムアウトになる可能性があるのと、連番を振って管理するなどしてエラー時の再送をやる場合、考慮無くやると、アホな結果を生む可能性もあるので、注意が必要です。このあたりの話題はソケット関係の情報を検索すると出てくると思います。

あまり厳密にやると複雑化する気もするので、シンプルにタイムアウトでの対処がいいかなと思います。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング