
疑問に思ったので教えて下さい。
以下のようにBeginReceive処理を複数回行うとエラーが発生します。
これは1つのポートにおけるバッファが限界に達したためなのでしょうか。
' 変数宣言
lUdpClient = New UDPState()
lUdpClient.netPoint = New Net.IPEndPoint(Net.IPAddress.Any, iLocalPort)
lUdpClient.udp = New Net.Sockets.UdpClient(lUdpClient.netPoint)
For i = 0 To 3000
lUdpClient.udp.BeginReceive(AddressOf SendData, lUdpClient)
Next
システムのバッファ領域が不足しているか、またはキューがいっぱいなため、ソケット操作を実行できませんでした。
No.4ベストアンサー
- 回答日時:
> 一度Sendした場合、受信待ち状態が解除されるので、
> 再度BeginReceiveを呼び出しています。
元々コールバック関数中でBeginReceiveを呼び出しておらず,
その場合には一度だけコールバック関数が呼ばれるために,
Sendで受信待ち状態が解除されると勘違いした,ということはないですか。
UdpClient.Sendはsendto WinSock2 APIを呼び出すのですが,
このAPIはRecvFrom WinSock2 APIによるoverlapped I/Oを阻害しません。
わかりにくいなら,受信用のソケットと送信用のソケットを分離してしまうのも一つの方法だと思います。
大変申し訳ありません。
ご指摘の通り、BeginReceiveの認識に誤りがありました。
コールバック関数中でBeginReceiveは呼び出していたのですが、
送信処理でもBeginReceiveを呼び出していました。
Sendを実行すると受信待ちが解除されるのだと思っていました。
送信処理にあるBeginReceiveを削除したところ、正常に動作するようになりました。
いつも1時間で落ちていたのに4時間経っても問題ありません。
ありがとうございました。
No.3
- 回答日時:
> lUdpClient.udp.BeginReceive(New System.AsyncCallback(AddressOf receivecallback), lUdpClient) #ここでエラー
ここは送信処理を行うのではないのですか?
どう見ても受信処理をさせようとしていますが。
実際に送信するつもりでBeginReceiveしていれば,
タイマーでBeginReceiveの呼び出しが蓄積していきますから例外が発生します。
ご回答ありがとうございます。
申し訳ありません。ソースが足りませんでした。
以下のように送信処理を行っています。
' リモートホストを指定してデータを送信
lUdpClient.udp.Send(sendBytes, sendBytes.Length, remoteHost, remotePort)
lUdpClient.udp.BeginReceive(New System.AsyncCallback(AddressOf receivecallback), lUdpClient) #ここでエラー
一度Sendした場合、受信待ち状態が解除されるので、
再度BeginReceiveを呼び出しています。
やはり送信処理中にBeginReceiveを使用しているのが原因なのでしょうか。
しかし、受信待ち状態にするにはこの方法しかないと思い、
仕方なくBeginReceiveを使用しています。
No.2
- 回答日時:
大量にUdpClientでBeginReceiveさせ例外を起こさせたところ,どうもOS側のキューが不足しているようです。
# 手元の環境のソースだと,Socket.csの4967行目。
なので,ThreadPoolは関係ありませんでした。
WSARecvFrom APIのエラーにもWSAENOBUFSはないので,通常は起こらないと見られているのでしょう。
確実な解決策は,overlapped I/Oの数を減らすことしかないと思います。
まず,BeginReceiveをそれだけたくさん行う必要があるのでしょうか。
例えば,最大で3個程度作るだけにしてしまえば,この例外が起きることはなくなると思います。
# 20件/secであればこれでさばけると思いますが。
ご回答ありがとうございます。
送信処理はTimer、受信処理はBeginReceiveを使用しているのですが、
うまくいきません。
Private Sub SocketsReception()
' 変数宣言
lUdpClient = New UDPState()
lUdpClient.netPoint = New Net.IPEndPoint(Net.IPAddress.Any, iLocalPort)
lUdpClient.udp = New Net.Sockets.UdpClient(lUdpClient.netPoint)
' 受信処理開始
lUdpClient.udp.BeginReceive(New System.AsyncCallback(AddressOf receivecallback), lUdpClient)
End Sub
Public Sub receivecallback(ByVal AR As IAsyncResult)
Try
Dim ClientData As UDPState = New UDPState()
Dim LU As Net.Sockets.UdpClient = CType(AR.AsyncState, UDPState).udp
Dim LE As Net.IPEndPoint = CType(AR.AsyncState, UDPState).netPoint
Dim receiveBytes As Byte() = LU.EndReceive(AR, LE)
Dim receiveString As String = enc.GetString(receiveBytes)
Dim receiveAddress As System.Net.IPAddress = LE.Address
'---受信処理を行う---
lUdpClient.udp.BeginReceive(New System.AsyncCallback(AddressOf receivecallback), lUdpClient)
' データ異常の場合
Catch ex As System.Net.Sockets.SocketException
' 終了処理
Catch ex As Exception
End Try
End Sub
Private Sub Timer2_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer2.Tick
'---送信処理を行う---
lUdpClient.udp.BeginReceive(New System.AsyncCallback(AddressOf receivecallback), lUdpClient) #ここでエラー
' 送信エラー
Catch ex As System.Net.Sockets.SocketException
' 終了処理
lUdpClient.udp.Close()
SocketsReception()
End Try
bSendOn = False
End Sub
No.1
- 回答日時:
えーっと,OSが認識するプロセッサの個数 (タスクマネージャのパフォーマンスタブのCPUの個数) はいくつですか。
これが3以下であれば,3001個もスレッドを非同期I/Oを同時に実行することはできません。
# 4以上でも,3001個も非同期I/Oを作るのが良いとは言えませんが。
可能であるならば,そもそもBeginReceiveの回数を減らし,コールバック関数で再度BeginReceiveするなどしてみてはどうでしょうか。
参考URL:http://msdn.microsoft.com/ja-jp/library/system.t …
ご回答ありがとうございます。
デュアルコアですので2つになります。
>可能であるならば,そもそもBeginReceiveの回数を減らし,コールバック関数で再度BeginReceiveするなどしてみてはどうでしょうか。
コールバック関数で再度BeginReceiveを実行したところ1時間ほどで同じ下記エラーが発生しました。
1秒間に20回くらいUDPでデータを受信しているため、パケットの量が多すぎてエラーになったのでしょうか。
システムのバッファ領域が不足しているか、またはキューがいっぱいなため、ソケット操作を実行できませんでした。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
winsockでソケット通信の開発を...
-
「スイッチングハブのバッファ...
-
socket: recvはいつ,どれだけ...
-
Linuxでのシリアル通信について...
-
recv関数の受信結果について
-
TCP/IP通信プログラミングにお...
-
TCPでの非同期型select関数につ...
-
ClearCommError呼び出し時のCE_...
-
シリアルポート通信
-
SocketのSend関数でのCLOSEの検...
-
WriteFile()でのデータ送信がで...
-
winsockの動作について。
-
SerialPortのDataReceivedイベ...
-
WinsockAPIのrecvfromの受信デ...
-
シリアル通信エラー
-
rs232cでの受信データ(mscomm)...
-
DirectXでの周波数(音程)変更
-
Macターミナルで実行中のプログ...
-
バックグラウンドのプロセスの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
winsockでソケット通信の開発を...
-
WriteFile()でのデータ送信がで...
-
シリアル通信の出力バッファと...
-
socket: recvはいつ,どれだけ...
-
「スイッチングハブのバッファ...
-
Linuxでのシリアル通信について...
-
COMポートの同時オープン同時読...
-
シリアル通信エラー
-
SerialPortのDataReceivedイベ...
-
【CAsyncSocket::OnReceive()呼...
-
ソケット通信内 read関数について
-
ftplibのエラー処理
-
recv関数の受信結果について
-
rs232cでの受信データ(mscomm)...
-
UDP処理のエラーについて
-
SocketのSend関数でのCLOSEの検...
-
TCP/IP通信プログラミングにお...
-
winsockの動作について。
-
シリアル通信 大きいサイズの...
おすすめ情報