
No.4ベストアンサー
- 回答日時:
通信認証のサンプルを作成しました。
(正確に言うと、以前に作成したものがあって、それを抜粋しました)
プロジェクトは二つ必要で、サーバーとクライアントに分かれています。
それぞれにプロジェクトを作成して、EXEを作成してください。
基本はサーバーのEXEが立ち上がった状態で、クライアントのEXEを起動してください。
この書き込みの下の方に「共通の標準モジュール」を記してますが、[INIT_PORT][SERVER_NAME]の各定数があります。
こちらは環境に合わせて変更をしてください。
もし、一台のマシンで実験をするのであればSERVER_NAMEをご自分のマシン名に変更をしてください。
プログラムが正常に動くと、サーバー、クライントが交互に通信状況をメッセージボックスで知らせます。
これはあくまでサンプルなのでそのようにしてますが、サーバー側にはメッセージボックスの機能を使用しないでください。メッセージボックスが表示されている間は、他のユーザーとの通信ができなくなってしまいます。
(VBでそれを回避する方法があるのですが、動作が不安定になるために書きません)
このサンプルでは、互いに文字列を送信しています。
実践では、その文字列をパスワード認証に使用してはいかがでしょうか?
必要なもの
Project1.vbp(サーバー用)
フォーム
Winsock1(インデックスなし)
Winsock2(インデックスあり)
Project2.vbp(クライアント用)
フォーム
Winsock1(インデックスなし)
Winsockはメニューバーより
[プロジェクト]
[コンポーネント]
[Microsoft Winsock Control 6.0(かな?)]
を選択したらツールボックスにWinsockコントロールが現れます。
それをサーバー側に二つ、クライアント側に一つ、各フォームに貼り付けます。
サーバー側のWinsock2にはIndexプロパティに'0'ゼロをセットしてください。
その他のWinsockには値を入力しないでください。
あとは下のソースを貼り付けてください。
-----サーバーのフォーム内のソース(ここから)---------
Option Explicit
Private Sub Form_Load()
Me.Caption = "SERVER"
'ポートの初期化を行い、受信待ち状態にする
On Error GoTo PGMERR
With Me.Winsock1
.LocalPort = INIT_PORT
.Listen
End With
Exit Sub
PGMERR:
Call MsgBox("通信ポートに以上が見られました、終了いたします。", vbSystemModal, Me.Caption)
End
End Sub
'フォームが閉じる前に、Winsockを全て閉じる
Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim wkSock As Winsock
With Me
.Winsock1.Close
For Each wkSock In .Winsock2
wkSock.Close
Next wkSock
End With
End Sub
'特定のクライアントのソケットを閉じたとき
Private Sub Winsock2_Close(Index As Integer)
With Me
.Winsock2(Index).Close
Unload .Winsock2(Index)
End With
End Sub
'メッセージデータの受信
Private Sub Winsock2_DataArrival(Index As Integer, ByVal bytesTotal As Long)
Dim strRecvData As String '送られてきたデータ
Dim lngRecvCnt As Long '送られてきたデータライン数
Dim valRecvAry As Variant '送られてきたデータをライン数のに分解し配列にして記憶
Dim wkVal As Variant '受信したメッセージ1文を、IDとメッセージに分解して配列で記憶
Dim wkSType As SOCKMSG_ID '分解した1文のID
Dim wkStr As String '分解した1文のメッセージ
Dim i As Long 'ループカウンタ
Dim wkMsg As String '送信するメッセージ
With Me
'メッセージを受け取る
.Winsock2(Index).GetData strRecvData
'受信メッセージを、メッセージ分の配列にする
valRecvAry = Split(strRecvData, vbCrLf)
'メッセージ数を取得
lngRecvCnt = UBound(valRecvAry)
'受信メッセージの分だけ、一文ずつ処理を行う
For i = 0 To lngRecvCnt - 1
'一文をIDとメッセージに分解
wkVal = Split(valRecvAry(i), vbNullChar)
wkSType = wkVal(0)
wkStr = wkVal(1)
Select Case wkSType
Case SOCKMSG_ID.ID1
wkMsg = "山川豊"
Call MsgBox("ID1で[" & wkStr & "]を受信しました" & vbNewLine & vbNewLine _
& "ID1で[" & wkMsg & "]を送信します", vbSystemModal, Me.Caption)
Call SendMsg(.Winsock2(Index), ID1, wkMsg)
Case SOCKMSG_ID.ID2
wkMsg = "起動してもいいよ"
Call MsgBox("ID2で[" & wkStr & "]を受信しました" & vbNewLine & vbNewLine _
& "ID2で[" & wkMsg & "]を送信します", vbSystemModal, Me.Caption)
Call SendMsg(.Winsock2(Index), ID2, wkMsg)
End Select
Next i
End With
PGMEND:
End Sub
'接続要求がきたら、新たなWinsockを用意する
Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
Dim lngNewIndex As Integer
lngNewIndex = 0
On Error Resume Next
With Me
'新たな受信装置を1つ追加する
Do
Err.Clear
lngNewIndex = lngNewIndex + 1
Load .Winsock2(lngNewIndex)
Loop Until Err.Number = 0&
On Error GoTo 0
.Winsock2(lngNewIndex).Accept requestID
End With
End Sub
-----サーバーのフォーム内のソース(ここまで)---------
-----クライアントのフォーム内のソース(ここから)-------
Option Explicit
'フォームロード時に接続を試みる
Private Sub Form_Load()
Me.Caption = "CLIANT"
With Me.Winsock1
.RemoteHost = SERVER_NAME
.RemotePort = INIT_PORT
.LocalPort = 0
.Connect
End With
End Sub
'サーバーが落ちた
Private Sub Winsock1_Close()
Call MsgBox("サーバーが落ちたー", vbSystemModal, Me.Caption)
Unload Me
End Sub
'サーバーと接続できた
Private Sub Winsock1_Connect()
Dim wkMsg As String
wkMsg = "岸部四郎"
Call MsgBox("接続できた" & vbNewLine & vbNewLine _
& "ID1で[" & wkMsg & "]を送信します", vbSystemModal, Me.Caption)
Call SendMsg(Me.Winsock1, ID1, wkMsg)
End Sub
'サーバーと接続できなかった
Private Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
Call MsgBox("接続できなかった", vbSystemModal, Me.Caption)
Unload Me
End Sub
'メッセージデータの受信
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strRecvData As String '送られてきたデータ
Dim lngRecvCnt As Long '送られてきたデータライン数
Dim valRecvAry As Variant '送られてきたデータをライン数のに分解し配列にして記憶
Dim wkVal As Variant '受信したメッセージ1文を、IDとメッセージに分解して配列で記憶
Dim wkSType As SOCKMSG_ID '分解した1文のID
Dim wkStr As String '分解した1文のメッセージ
Dim i As Long 'ループカウンタ
Dim wkMsg As String '送信するメッセージ
With Me
'メッセージを受け取る
.Winsock1.GetData strRecvData
'受信メッセージを、メッセージ分の配列にする
valRecvAry = Split(strRecvData, vbCrLf)
'メッセージ数を取得
lngRecvCnt = UBound(valRecvAry)
'受信メッセージの分だけ、一文ずつ処理を行う
For i = 0 To lngRecvCnt - 1
'一文をIDとメッセージに分解
wkVal = Split(valRecvAry(i), vbNullChar)
wkSType = wkVal(0)
wkStr = wkVal(1)
Select Case wkSType
Case SOCKMSG_ID.ID1
wkMsg = "鳥羽一郎"
Call MsgBox("ID1で[" & wkStr & "]を受信しました" & vbNewLine & vbNewLine _
& "ID2で[" & wkMsg & "]を送信します", vbSystemModal, Me.Caption)
Call SendMsg(.Winsock1, ID2, wkMsg)
Case SOCKMSG_ID.ID2
Call MsgBox("ID2で[" & wkStr & "]を受信しました" & vbNewLine & vbNewLine _
& "通信を終了します", vbSystemModal, Me.Caption)
'''''ここに通信が正常にできたことを示すフラグを立てておく
Unload Me
End Select
Next i
End With
PGMEND:
End Sub
-----クライアントのフォーム内のソース(ここまで)-------
サーバー・クライアントのそれぞれに共通の標準モジュールとして、以下のソースを追加してください。
-----共通の標準モジュール(ここから)-------
Option Explicit
Public Enum SOCKMSG_ID
ID1 = 1
ID2 = 2
ID3 = 3
End Enum
Public Const INIT_PORT As Long = 8000 '←このPORTは使用される確立が高いので、適当な値に変更したほうがいいかも?
Public Const SERVER_NAME As String = "PC_MACHINE_NAME" '←サーバー用のEXEのをおくマシン名
Public Sub SendMsg(inSock As Winsock, inSendType As SOCKMSG_ID, inSendMsg As String)
Dim wkStr As String
With inSock
'通信が可能なときに通信する
If (.State = (sckConnected)) Then
'通信の書式は
' 1.通信を送るときのID(SOCKMSG_IDを自分で作成、オリジナルの番号を振る)
' 2.vbNullChar(IDとメッセージとの区切り文字)
' 3.メッセージ(任意の文字列)
' 4.vbCrLf(文末を示す)
wkStr = inSendType & vbNullChar & inSendMsg & vbCrLf
'メッセージを送る
.SendData wkStr
End If
End With
End Sub
-----共通の標準モジュール(ここまで)-------
そう簡単に作れるものではありませんよね。
本当にありがとうございます。
winsockは使ったことありますので、
サンプルから発展させられればと思います。
助かります。
No.3
- 回答日時:
サンプルを作ってみようと思うのですが・・・
機能1.ドメイン
「ドメイン」という意味はわかりますか?
まずこちらから「ネットワークにドメインサーバーがあるかないか」という質問をこしたいのですが、、、
会社にはサーバーがありますよね?
もし意味がわからなかったら、会社のサーバー管理者に
「うちのネットワークにはドメインサーバーがあるの?」と聴いてみてください。
ドメインサーバーがないのであれば、この方法は無理です。
機能2.通信
ファイルサーバーでも何でもいいので、一台のマシンが通信の受信待ち状態で待機するEXEを起動する。
それで今回問題の社外に持ち出されたら困るEXEを起動する。
このとき通信を行う。
通信ができないのであれば、EXE終了
この二つの機能がメインです。
ですのでドメインを使用してるかどうかを教えてください。
ちなみに仕事の合間にサンプルを作成しておりますので(←いいのか?)、ちーと時間がかかると思います。
No.2
- 回答日時:
ykkw_2001さんのおっしゃる通り、環境次第でどうにでもなりそうですね。
IPアドレスで確認しきれないということはDHCPを導入してるとか?
もしそれなら、ユーザー名が取れるし、ワークグループではなくドメインを使用したら、ネットワークに参加=社内環境とできるのでは?
なので、EXEにドメイン固定のロジックを追加してしまえばよいと思います。
さらに認証パスワードを起動時に入力などなど。
サーバーにもうひとつのEXEを用意して、そちらと通信が可能なときのみEXEが起動可能という方法もあります。
ありがとうございます。
勉強不足で、”EXEにドメイン固定のロジックを追加してしまえばよいと”
理解できません。
具体例を挙げていただければ幸いです。
No.1
- 回答日時:
利用環境次第でどうにでもなりそうですけど・・・
たとえば、IPで確認はダメなように書かれていますが、イントラネットの特定アドレスのマシンで認証するとか。
社内専用アプリケーションの存在をレジストリで確認してから、動作させるとか。
ID+パスワードに時間を絡めて、1回だけ実行できるようにするとか。
はずしてたらゴメンです。
どうもありがとうございました。
説明不足ですみません。
>社内専用アプリケーションの存在をレジストリで確認してから・・・
ん~。むずかしいですね。
アプリで社内専用がわかればいいんですけど・・。
パスワードは平気で渡す輩がいて・・。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- サーバー Googleドライブなどを使わずにテザリングAndroidでWindowsとファイル共有 1 2023/02/19 13:14
- C言語・C++・C# exeファイルが作れない(windows10) 6 2022/08/13 08:47
- その他(インターネット接続・インフラ) アプリ利用者を特定し、裁判に 2 2022/06/09 21:43
- Visual Basic(VBA) VBA アドインについて お詳しい方 ご教授をお願いします。 相談事項 現在以下の対応を実施した所、 1 2022/11/02 16:53
- その他(プログラミング・Web制作) プログラムの起動、利用について、使用期間を設定する方法 3 2023/08/06 21:03
- セキュリティホール・脆弱性 テレワークで会社支給パソコン以外でVPN接続を制限するやり方 教えて下さい 3 2022/08/31 12:40
- 労働相談 合意済み仕様の商品納入後における仕様変更要求への対応について 5 2023/04/19 09:41
- Windows 10 Windows11の実行モジュールはどこにある 1 2022/05/31 07:33
- Windows 10 このWindowsUpdateの失敗メッセージは何を物語るか? 5 2023/07/17 11:49
- その他(プログラミング・Web制作) マウスオーバー→ホイール回転でスクロールできない 2 2022/10/31 10:06
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
waveIn、waveOutでの音声録音・...
-
誤り制御方式の誤り検出再送要...
-
「スイッチングハブのバッファ...
-
rs232cでの受信データ(mscomm)...
-
シリアル通信 大きいサイズの...
-
DirectXでの周波数(音程)変更
-
TCP/IP通信プログラミングにお...
-
WaitForMultipleObjects関数の...
-
exeファイルのセキュリティ。
-
popen実行時にバッファが空の場合
-
Macターミナルで実行中のプログ...
-
ホームページビルダー 文字化け
-
VBAの配列サイズとメモリに関して
-
TCP/IP通信時のサーバーからの受信
-
三次元のグラフを書きたいので...
-
サンク方式について
-
USBハブの自作について
-
構文エラーについて教えてください
-
スーパーのレジ待ち
マンスリーランキングこのカテゴリの人気マンスリー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の動作について。
-
シリアル通信 大きいサイズの...
おすすめ情報