私はUDPソケットをiOS上で使用しています。ノンブロッキングモードに設定したり、不正な接続をシミュレートすると、私は非常に奇妙な動作を経験します。通常のfcntl
と非ブロックモードでソケットを設定するにはUDPソケットのインコヒーレントな動作
:
fcntl(socketfd, F_SETFL, O_NONBLOCK);
5/5イン/アウト、パケットロスや50KBpsと私はネットワークリンクConditioneerを使用し、接続不良をシミュレートするには限界(保証します私の場合、システムのバッファはある時点でいっぱいになるでしょう)。
私はsendto()
でデータを送信し、clock()
とprintf()
でコールをします。ここで
私のテストからのデータを、ミリ秒でのデータです:
- ブロッキング、良好な接続:
min 0
/max 929
//std 111
- ブロッキング、接続不良:
min 0
/max 611
/avg 38
/std 84
- 非ブロッキング、接続良好:
min 0
/max 6244
/avg 601
/std 1071
- 非ブロッキング、接続不良:
min 0
/max 5774
/avg 400
/std 747
は私もsendto()
がすぐに戻ってきたことを意味し、場合2
に多くのエントリが0 ms
であることがわかり、低説明ケースの平均および標準偏差。
いつも、sendto()
は、送信が要求されたバイト数に対応する正の値を返しました。
:
- モードをブロックで、私はそれではなく、データがあると思われ、データを格納するために利用可能なシステムバッファがあるまで、それはブロックすることが予想されるがスペースが実際に存在するまで、私が代わりにデータから、
sendto()
は、それがブロックされるエラーを返すことを期待する非ブロックモードで - (すぐに呼び出しが戻るので)捨て
Th eの動作は反転しているように見えますが、sendto
はエラーを報告しません。
私は間違っていますか?
ソケットの作成:への送信
int socketfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
// error checks
setsockopt(socketfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));
int tos = 0xB8; // VOICE
setsockopt(socketfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
int rc = fcntl(m_iSocket, F_SETFL, O_NONBLOCK);
if (rc != 0) {
// error of fcntl is notified
}
:
sendto(socketfd, buffer, buffer_length, 0, (struct sockaddr *) &m_sRemoteHost, sizeof(m_sRemoteHost))
私はUDPがいかなる保証も提供しないことを理解します。私はまた、フロー制御が関与していないことを理解しています。なぜ私が理解できないのは、sendto()コールの時間が接続品質によって大きく変わるのか、それがどうして変化するのかを解釈できないことです。完全な送信バッファのためにパケットが実際にシステムによって廃棄されたことを実際に検出する方法はありますか?フロー制御がないので、バッファーはいっぱいになる可能性がありますか? –