- PR -

SetSocketOptionのReuseAddress

1
投稿者投稿内容
KT工房
常連さん
会議室デビュー日: 2006/06/20
投稿数: 49
投稿日時: 2008-10-09 17:10
現在Socketにて通信を行っていますが、
接続を切って再接続をする場合に接続ができなくて困っています。
PORTがTIME_WAITでまだ解放されていないから接続できないのはわかりましたが、
SetSocketOptionのReuseAddressを設定すれば接続可能なはずですよね?

なにか使い方が間違っているのでしょうか?
以下に簡単に現在のソースを記述しますので、ご指摘お願いします。

Private _connectSocket As Socket
Private _rcvBuf(100) As Byte

'**************************************************************************
' btnConnect_Click
'**************************************************************************
Private Sub btnConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConnect.Click

'Create Socket
_connectSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

_connectSocket.ExclusiveAddressUse = False
_connectSocket.Blocking = True

_connectSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, 1)
_connectSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1)

_connectSocket.Bind(New IPEndPoint(IPAddress.Any, 2001))

_connectSocket.BeginConnect(New IPEndPoint(IPAddress.Parse("192.168.0.10"), 2001), AddressOf ConnectCallback, Nothing)
End Sub


'**************************************************************************
' btnDisconnect_Click
'**************************************************************************
Private Sub btnDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDisconnect.Click

'Close Socket
If Not _connectSocket Is Nothing Then

If _connectSocket.Connected Then
_connectSocket.Disconnect(True)
End If

'Socket Close
_connectSocket.Close()
_connectSocket = Nothing
End If
End Sub


'**************************************************************************
' ConnectCallback
'**************************************************************************
Private Sub ConnectCallback(ByVal AResult As IAsyncResult)

Try
'Connect Completed
If AResult.IsCompleted Then

'Connect Request End
_connectSocket.EndConnect(AResult)

'Begin Receive
_connectSocket.BeginReceive(_rcvBuf, 0, _rcvBuf.Length, _
SocketFlags.None, AddressOf ReceiveCallback, _connectSocket)
End If

Catch ex As SocketException

MsgBox(ex.Message)
Catch ex As Exception

MsgBox(ex.Message)
End Try
End Sub


'**************************************************************************
' ReceiveCallback
'**************************************************************************
Private Sub ReceiveCallback(ByVal AResult As System.IAsyncResult)

End Sub


よろしくお願いします。

あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2008-10-09 20:19
サーバー側がCLOSEDになってないからだと思います。

Bind()しなければいいんじゃないですか?
クライアント側のポートを固定するのは避けた方が無難かと。
KT工房
常連さん
会議室デビュー日: 2006/06/20
投稿数: 49
投稿日時: 2008-10-10 10:56
返答ありがとうございます。
サーバー側(PLC)は確かにハーフコネクションとなりCLOSEDになっていません。
ポート固定に関してはシーメンスPLCの仕様?のため避けれません。

色々調べてみたところTCPの仕様で切断後一定時間待機(TIME_WAIT)させられるようです。
この時間をWindowsデフォルトの4分から30秒に変更はできるようですが、
瞬時に再接続は無理そうな感じです。
試しに1秒に設定しましたが、設定最小値の30秒まで解放されませんでした。

progman
大ベテラン
会議室デビュー日: 2005/06/08
投稿数: 227
投稿日時: 2008-10-10 13:19
ReuseAddrはサーバの待ちうけ動作を想定して考えられたオプションです。
クライアント側のローカルポートをany(0)とすることでダイナミックに振られる
ポート番号で重複は避けられるので、そういった(再使用)考慮の仕組みをわざわざ
オプションとして用意してないんではないでしょうか。

私はVBのソースはわかりませんが、、、
あしゅさんはクライアント側のポート番号の固定をやめましょう。と指摘されてるの
です。クライアント側固定も仕様なのでしょうか。

KT工房
常連さん
会議室デビュー日: 2006/06/20
投稿数: 49
投稿日時: 2008-10-10 16:18
クライアント側固定も仕様なので、現状では回避策は見当たりませんよね・・・。
1

スキルアップ/キャリアアップ(JOB@IT)