疑問に思ったので教えて下さい。
以下のように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で質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 実行時エラー´5854´ 文字列型パラメーターが長すぎます。 3 2023/06/08 21:17
- 英語 "by a ~ 0.5 percentage point"が単数となる理由等について 2 2023/05/11 10:41
- C言語・C++・C# C# で、あるフォルダー内にあるすべてのテキストファイルを別のフォルダーにコピーする。 4 2022/11/21 13:23
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- Excel(エクセル) エクセルシート中の全角英数字を半角に変換したい 4 2022/07/07 13:14
- Visual Basic(VBA) 複数のcsvファイルをExcelに一括変換したい 2 2023/03/03 12:44
- Visual Basic(VBA) 複数シートの複数列に入力されているデータを重複なしで抽出するVBAを作りたいです。 9 2022/06/17 10:33
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
- Visual Basic(VBA) ①ExcelVBAでカレンダーを作り、別のユザーフォームで日付を入力したいのですがエラーになります。 1 2023/02/17 18:39
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
Connection reset by peer
-
winsockでソケット通信の開発を...
-
TCPでの非同期型select関数につ...
-
SocketのSend関数でのCLOSEの検...
-
Cの receive関数でメモリ不足...
-
mscommの受信バッファ異常について
-
exeファイルのセキュリティ。
-
socket: recvはいつ,どれだけ...
-
10.3.9付属Mailの再構築をした...
-
RS232C通信(PC⇔PLC)
-
ReadFile(GPSとの通信)Win7で...
-
「スイッチングハブのバッファ...
-
WriteFile()でのデータ送信がで...
-
Macターミナルで実行中のプログ...
-
緯度、経度の 10進法と 60進法...
-
バックグラウンドのプロセスの...
-
C言語で、メモリを解放しないで...
-
Excelでのセル内容の高速消去方法
-
MFCアプリケーションでの終了コ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
winsockでソケット通信の開発を...
-
「スイッチングハブのバッファ...
-
socket: recvはいつ,どれだけ...
-
WriteFile()でのデータ送信がで...
-
RS-232Cでバイナリデータを受信...
-
recv関数の受信結果について
-
Connection reset by peer
-
rs232cでの受信データ(mscomm)...
-
シリアル通信の出力バッファと...
-
シリアル通信 大きいサイズの...
-
SocketのSend関数でのCLOSEの検...
-
WinsockAPIのrecvfromの受信デ...
-
RS232C通信(PC⇔PLC)
-
ソケット通信内 read関数について
-
VB2010 シリアル受信した情報を...
-
C#で通信処理。応答がない場合...
-
SerialPortのDataReceivedイベ...
-
winsockの動作について。
-
COMポートの同時オープン同時読...
おすすめ情報