DOBON.NET DOBON.NETプログラミング掲示板過去ログ

ライセンスがある場合の端末の管理?

環境/言語:[C#,.NET Framework2]
分類:[.NET]

少しC#のプログラムの質問とは、違うかもしれませんが、何か良いアイディアを
教えていただけたら光栄です。
あるソフトを使用できる同時接続のライセンスが10個で、
それに対しそのソフトが入っているパソコンが15台の環境に、
それぞれの端末でC#のプログラムがそのソフトを起動するのですが、
プログラムで、ログイン画面の個所で、テーブルを見に行き、
ライセンスの違反にならないように制御を掛ける仕様書を書きました。
仕様は、あるテーブルにMACHINE_ID,ONというフィールドを作成し、
マシン分のデータを作成し、今回なら15データ。
MACHINE_IDには、それぞれの端末ID。
ONには、接続をしていた場合、フィールドをtrueにし、ログアウトした場合、falseにするという風にしました。
しかし、いざ仕様書を提出すると上司に、
・ある端末でログイン中に電源が落ちた場合はどうするのだ?フィールドがONになったままではないのか?
・端末が増えた場合、そのたびにわざわざお客様の所にいって、データを足すのか?
と言われてしまいました。
確かに上司の言っている事はあっています。
しかし、私の考えではそれ以上よいアイディアが浮かびませんでした。
ライセンス違反をしないように作りこむ何か良い技は無いでしょうか?
いろいろな企業で働いている方でこんな状況に陥った事とかは無いでしょうか?
何でも良いので何かあればよろしく御願いします。
素人考えで申し訳ありませんが,
UDPでマルチキャストで発信して,返事をよこした数を数えるというのはだめ
ですかね。
(UDPを遮断すると15台全部使えちゃうか...)
YASさんありがとうございました。
しかし、あんまりUDPに関して良く分かっておりません。
もう少し詳しく教えていただけたら光栄です。
一応、インターネットで確認してみました。
TCPより軽いのがうりだとか・・・
C#で簡単に書けるものなのでしょうか・・・
明日、ちょっと試みてみます。
■No19861に返信(ちとせさんの記事)
なんにせよ、サーバー側で管理するプログラムは必要そうですね。

通信については初心者なんですが、今のボクが実現できそうな案を
書いてみます。

System.Runtime.Remoting あたりを使います。ボクがやったときは
[VB.NET2003]の本を見たので、WEBの資料を用意できませんが、
http://support.microsoft.com/kb/300943/ja
あたりの話です。
System.Runtime.Remoting.Channels.Tcp を利用してサーバー上の
サービスから値を取得します。

DBの管理用テーブルのフィールドは、[端末名][ログインフラグ]
を用意します。

・サーバーで接続数管理用のサービスを用意。
・クライアントはログイン時、サービスに自端末名を送信。
・サービスは端末名が新規なら登録、[ログインフラグ]を
カウントし、ログイン許可・不許可を戻り値で返します。
・ログイン許可した端末の[ログインフラグ]を立てます。
・ログイン中、クライアントは一定時間(10秒とか)ごとに
サービスにログイン継続中の情報(自端末名)を送ります。
・サービスは、一定時間(3分とか)クライアントから
ログイン継続中の情報が来ないとログアウトしたと見なし、
[ログインフラグ]を戻します。
> System.Runtime.Remoting あたりを使います。ボクがやったときは
> [VB.NET2003]の本を見たので、WEBの資料を用意できませんが、
> http://support.microsoft.com/kb/300943/ja
> あたりの話です。
> System.Runtime.Remoting.Channels.Tcp を利用してサーバー上の
> サービスから値を取得します。
>
> DBの管理用テーブルのフィールドは、[端末名][ログインフラグ]
> を用意します。
>
> ・サーバーで接続数管理用のサービスを用意。
> ・クライアントはログイン時、サービスに自端末名を送信。
> ・サービスは端末名が新規なら登録、[ログインフラグ]を
> カウントし、ログイン許可・不許可を戻り値で返します。
> ・ログイン許可した端末の[ログインフラグ]を立てます。
> ・ログイン中、クライアントは一定時間(10秒とか)ごとに
> サービスにログイン継続中の情報(自端末名)を送ります。
> ・サービスは、一定時間(3分とか)クライアントから
> ログイン継続中の情報が来ないとログアウトしたと見なし、
> [ログインフラグ]を戻します。

アドバイスありがとうございました。
http://support.microsoft.com/kb/300943/ja
http://support.microsoft.com/kb/300951/ja
ここらへんを一応見て、やってみようと思ったのですが、なかなかうまくいきません。
というよりかあまり理解出来ていないといったのが本音です。
ここでいうサービスというのはどういう意味のサービスなのでしょうか?
よろしくお願いします。
たびたびすみません。
・ログイン中、クライアントは一定時間(10秒とか)ごとに
> サービスにログイン継続中の情報(自端末名)を送ります。
あと、この個所が良く分からないのです。
このように10秒単位で処理を引き起こすのはどうすれば出来るのでしょうか?
クライアントって何かしら画面とかが開いていると思うのですが、
ユーザが何もせずに、処理を引き起こす事って可能なのでしょうか?
■No19861に返信(ちとせさんの記事)
> YASさんありがとうございました。
> しかし、あんまりUDPに関して良く分かっておりません。
> もう少し詳しく教えていただけたら光栄です。
> 一応、インターネットで確認してみました。
> TCPより軽いのがうりだとか・・・
> C#で簡単に書けるものなのでしょうか・・・
> 明日、ちょっと試みてみます。

例えば次のようなコードを各PCに仕込んでおいて,起動時に「Hello!」を
送信し,各PCからコンピュータ名が返されるのでその数を数えるというのは
どうでしょう?

Imports system.net.sockets
Imports system.Net
Imports System.Text
Imports System.Threading

Public Class Form1
    Private Udp As UdpClient
    Private UdpListenerThread As Thread

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        UDPSender("Hello!")
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'UDPをマルチスレッドで受信する
        UdpListenerThread = New Thread(AddressOf UDPListener)
        UdpListenerThread.IsBackground = True
        UdpListenerThread.Start()
    End Sub

    Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        '受信スレッド終了
        If Not IsNothing(Udp) Then
            Udp.Close() '受信スレッドは例外で終了する
        End If
        '受信スレッド終了の確認
        If Not IsNothing(UdpListenerThread) AndAlso Not UdpListenerThread.Join(1000) Then
            '終了が確認できないときは強制終了
            UdpListenerThread.Abort()
        End If
    End Sub

    'UDPでマルチキャストアドレスに送信する
    'マルチキャストアドレス224.168.1.1 ポート11000
    Public Sub UDPSender(ByVal s As String)
        Dim GrpAdd As IPAddress = IPAddress.Parse("224.168.1.1")
        Dim GrpPort As Integer = 11000
        Dim GrpEP As New IPEndPoint(GrpAdd, GrpPort)
        Dim UdpSender As New UdpClient
        Try
            Dim Bytes As Byte() = Encoding.UTF8.GetBytes(s)
            UdpSender.Send(Bytes, Bytes.Length, GrpEP)
            UdpSender.Close()
        Catch ex As Exception
            If Not IsNothing(UdpSender) Then
                UdpSender.Close()
            End If
        End Try
    End Sub

    'UDPでマルチスレッドアドレスから受信する
    'マルチキャストアドレス224.168.1.1 ポート11000
    Private Sub UDPListener()
        Dim GrpAdd As IPAddress = IPAddress.Parse("224.168.1.1")
        Dim GrpPort As Integer = 11000
        Dim grpEP As New IPEndPoint(GrpAdd, GrpPort)
        Dim Res As String
        Udp = New UdpClient(11000)
        Try
            Udp.JoinMulticastGroup(GrpAdd) 'マルチキャストグループに参加する
            Do
                Dim Bytes As Byte() = Udp.Receive(grpEP)
                Res = Encoding.UTF8.GetString(Bytes, 0, Bytes.Length)
                If Res = "Hello!" Then
                    UDPSender(My.Computer.Name)
                End If
                Debug.Print(Res)
            Loop
        Catch ex As Exception
            If Udp IsNot Nothing Then Udp.Close()
        End Try
    End Sub

End Class
■No19873に返信(ちとせさんの記事)
> ここでいうサービスというのはどういう意味のサービスなのでしょうか?
Windows サービスです。
[コントロールパネル]-[管理ツール]-[サービス]で現在実行されているサービスの一覧を
見ることができます。
[Windows サービスの概要]
http://www.cqpub.co.jp/hanbai/books/18/18371_WindowsService/18371_WindowsService.pdf
[方法 : Windows サービスを作成する]
http://msdn2.microsoft.com/ja-jp/library/9k985bc9(VS.80).aspx
チュートリアルに従えば、一応、サービスの作成は可能だと思うんですが。。。

WEB上でいい資料が見つかりませんでした。。。
たぶん↓に載ってたと思うんですが、数年前のことなのでうろおぼえです。
[プロフェッショナルVB.NET〈上〉基本編]
http://www.amazon.co.jp/gp/offer-listing/484431615X/

> ユーザが何もせずに、処理を引き起こす事って可能なのでしょうか?
???厳密な間隔(ミリ秒単位で正確に)とかいう条件でもなければ、画面に Timer コントロール
を1つ貼り付けるだけで実現できるのでは?
> 例えば次のようなコードを各PCに仕込んでおいて,起動時に「Hello!」を
> 送信し,各PCからコンピュータ名が返されるのでその数を数えるというのは
> どうでしょう?

これってアプリケーションの起動数がわかるだけではないですか?
接続しているかしてないかを返せば意味があるものにはなりますが。

そういうことを言いたいのではなくて、

「接続」ライセンスの話ですよね?
サーバー側が制限を越えたら単に拒否をするだけでクライアントも単に接続に失敗する、というだけのことではないのでしょうか?
それが「違反」と言われれば間違いではないでしょうが、
それを「道徳的」に回避しなければならないまでに至った理由は何でしょうか?
アプリケーションの性質?そのソフト固有の問題?
2007/06/20(Wed) 11:32:54 編集(投稿者)

■No19877に返信(まどかさんの記事)
確かにライセンスについての記述は不明瞭な部分を感じていました。

仕様としてある程度かたちになっているのでアドバイスしましたが、
そもそもライセンス違反にならないのか?についてはいまいち。。。

A:同時接続のライセンスが10個のソフト
B:C#のプログラム
とします。

・AとBは別のアプリケーションで、Bがまず接続を試みる。
・接続が可能ならBがAを起動する。
・それでライセンス違反にならない確認が取れている。
…という理解でいいでしょうか?

場合によっては
・Aを単独起動できた場合(Bが管理できていない状態。。。こっちを防ぐほうが大変そうな。。。)
・1つの端末でAを複数立ち上げた場合(接続が対象なら大丈夫そうな気もしますが)
などにも対応する必要がありそうですが。。。
サーバーアプリ等の接続ライセンスがあるものの場合、それ自体に接続数をオーバー
するような場合にメッセージ表示で起動しないものもあると思います。そーいった
機能との兼ね合いとか。。。確認できてるなら良いんですが。

DOBON.NET | プログラミング道 | プログラミング掲示板