TCPサーバーとして動作するVB6を使用して数年前にソフトウェアを作成し、クライアントから複数の接続を受け取りました。VB6 Winsock複数のTCP接続> DoEventsの問題
ソフトウェアの基本的なアイデアは、特定のポートでリッスンし、異なるクライアントからの接続を受け入れ、データを分析する別のwinsockに各接続を渡し、DBを探し、適切なメッセージで応答し、接続を閉じます。アプリケーションの起動時に
ソケットの初期化:
For i = 1 To MaxCon
Load sckAccept(i)
Next i
sckListen.Listen
の接続を受け入れること:ここで
は、いくつかのコードだPrivate Sub sckListen_ConnectionRequest(ByVal requestID As Long)
Dim aFreeSocket As Integer
aFreeSocket = GetFreeSocket
If aFreeSocket = 0 Then
sckAccept(0).Accept requestID
sckAccept(0).SendData "Server is full!"
sckAccept(0).Close
Else
sckAccept(aFreeSocket).Accept requestID
End Sub
受信データを、それを分析し、そして返信:
Private Sub sckAccept_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim sData As String
sckAccept(Index).GetData sData
'Do lots of analyizing and search in DB
'
'
sckAccept(Index).SendData "Message"
'
'
DoEvents
sckAccept(Index).Close
End Sub
すべてが正常に働いていたが、現在は接続数は、(毎秒カップルの数十)増加しているので、ソフトウェアが(理由DoEvents
の)Out of stack space
例外を取得し始めました。
多くの場合、DoEvents
が悪いですが、削除するとアプリケーションのUIが応答せず(スレッドの負荷が高いため)、一部のデータが配信されない可能性があります。
だから私の質問です:DoEvents
を使用してこの問題を回避する方法のアイデアはありますか?
注:私はVB6は本当にマルチスレッドをサポートしていないとこのような状況のためにPITAであるかもしれないことを知っています。私は実際にソフトウェアをアップグレードし、.Net
を使用してソフトウェアを再作成する予定ですが、それには時間がかかります。 VB6でこの問題を解決する必要があるのはこのためですが、今はVB6で書かれています。
私は正直なところ、doeventsがdataarrivalハンドラの最後の行になければならないと分かりません。重いループの中に入れてしまいます。技術的には、doeventsは単純な "yield"を実行するので、スタック不足エラーはsdataのサイズのような別のソースを持つ可能性があります。外部の配列に配置し、接続インデックスを使用してアクセスします。いくつかのヒープを保存するのに役立ちます。 – Gar
1 'DataArrival'ハンドラの中に' DoEvents'を入れます。なぜなら、 'Winsock.SendData'をトリガするからです。アプリケーションのUIは応答しません(スレッドの過負荷のため)。配送されない "。 2 - 「重い荷物」はどういう意味ですか? 3-スタックスペース不足エラーが発生すると、スタックは 'sckAccept_DataArrival'イベントでいっぱいになります。これは、 'DoEvents'がイベントを再度トリガーできるようにするためです(別の' DoEvents'を含むなど)。 4 - 'sData'のサイズはかなり小さいです(40-100バイト) –
私はdoeventsを使った理由を完全に理解しています。私はちょうどサブの終わりまでは見ません。ループ内で" doevents "ループはアプリケーションをロックしません。そしてたとえsdataが小さくても、あなたはわずかなスペースしか得られません。私はあなたの問題を引き起こすのは、未解決のtcpクエリーが(それらのハンドラーがそれらのデータベースを照会しているので)積み重なっていることも理解しています。 – Gar