(c) BigSpeed Computing Inc. - Secure private networking
VB6 example of secure chat and alert messaging application
'To keep this VB6 example simple, we are going to use
'only a single file transfer per direction at a time
Dim CallHandle As Long 'Handle to the calling socket
Dim UpSock As Long 'Handle to the uploading socket
Dim DownSock As Long 'Handle to the downloading socket
Dim UpFile As Long 'Handle to the uploaded file
Dim DownFile As Long 'Handle to the downloaded file
Dim UpCount As Long 'Number of the uploaded bytes so far
Dim DownCount As Long 'Number of the downloaded bytes so far
Dim UpSize As Long 'Size of the uploaded file
Dim DownSize As Long 'Size of the downloaded file
Dim UpName As String 'Name of the uploaded file
Dim DownName As String 'Name of the downloaded file
Dim DownPath As String 'Path to the downloaded file
Const pcALERT = 10 'Alert message ID
Const pcCHAT = 20 'Chat message ID
Const pcHAVE_FILE_HEAD = 30 'This is a file header
Const pcGIVE_FILE_BODY = 31 'Ask for file data
Const pcHAVE_FILE_BODY = 32 'This is file data
Const pcSTOP_UPLOAD = 33 'Stop the uploading transfer
Const pcSTOP_DOWNLOAD = 34 'Stop the downloading transfer
Const pcBUSY_DOWNLOAD = 35 'The download channel is taken
Private Declare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hwnd As Long, ByVal lpText As String, ByVal lpCaption As String, ByVal wType As Long) As Long
Private Sub ShowMessage(ByVal aText As String, ByVal aCaption As String)
Call MessageBox(0&, aText, aCaption, &H1000&)
End Sub
Private Function DirExists(ByRef aDir As String) As Boolean
Dim sResult As String
On Error Resume Next
sResult = Dir(aDir, vbDirectory)
On Error GoTo 0
DirExists = sResult <> ""
End Function
Private Function ExtractFileName(ByVal vStrFullPath As String) As String
Dim intPos As Integer
intPos = InStrRev(vStrFullPath, "\")
ExtractFileName = Mid$(vStrFullPath, intPos + 1)
End Function
Private Function ExtractFilePath(ByVal vStrFullPath As String) As String
Dim intPos As Integer
intPos = InStrRev(vStrFullPath, "\")
ExtractFilePath = Left$(vStrFullPath, intPos)
End Function
'Update the button state and the status text
Private Sub UpdateStatus()
Dim St As String
Dim LI As ListItem
Dim i, Sk, ConCnt As Long
'Buttons
If CallHandle > 0 Then
'a call is in progress
btnConnect.Enabled = False
btnCancel.Enabled = True
Else
'a new call can be initiated
btnConnect.Enabled = True
btnCancel.Enabled = False
End If
btnBrowse.Enabled = False
btnUpload.Enabled = False
txtUpload.Enabled = False
txtUpload.BackColor = &H80000000
If lvPeers.SelectedItem Is Nothing Then
btnRemove.Enabled = False
btnChat.Enabled = False
btnAlert.Enabled = False
Else
btnRemove.Enabled = True
btnChat.Enabled = SockLib.SessionOpen(lvPeers.SelectedItem.Tag)
btnAlert.Enabled = SockLib.SessionOpen(lvPeers.SelectedItem.Tag)
If SockLib.SessionOpen(lvPeers.SelectedItem.Tag) And (UpFile = 0) Then
'we can start a new upload process
btnBrowse.Enabled = True
btnUpload.Enabled = True
txtUpload.Enabled = True
txtUpload.BackColor = &H80000005
End If
End If
If UpFile <> 0 Then
'an upload process is in progress
btnAbortUp.Enabled = True
btnUpload.Enabled = False
Else
'no active upload process
btnAbortUp.Enabled = False
End If
If DownFile <> 0 Then
'a download process is in progress
btnAbortDown.Enabled = True
Else
'no active download process
btnAbortDown.Enabled = False
End If
'Status bar
If fSettings.txtKey.Text > "" Then
StatusBar.Panels.Item(1).Text = "Encryption: ON"
Else
StatusBar.Panels.Item(1).Text = "Encryption: OFF"
End If
If fSettings.chkCompress.Value = 1 Then
StatusBar.Panels.Item(2).Text = "Compression: ON"
Else
StatusBar.Panels.Item(2).Text = "Compression: OFF"
End If
If fSettings.chkServer.Value = 1 Then
StatusBar.Panels.Item(3).Text = "Server: ON"
Else
StatusBar.Panels.Item(3).Text = "Server: OFF"
End If
If lvPeers.ListItems.Count = 0 Then
St = "No active connection"
Else
St = Str(lvPeers.ListItems.Count) + " connected peer(s)"
End If
StatusBar.Panels.Item(4).Text = St
End Sub
'Set the component properties
Private Sub SetProperties()
If fSettings.txtKey.Text > "" Then
SockLib.SecurityMode = 2 'shared secret key
SockLib.SecretKey = fSettings.txtKey.Text
Else
SockLib.SecurityMode = 0 'no encryption
End If
SockLib.UseCompression = fSettings.chkCompress.Value
SockLib.StopListening
If fSettings.chkServer.Value = 1 Then
SockLib.StartListening (Val(fSettings.txtListenPort.Text))
End If
End Sub
'An alert message is available
Private Sub HaveAlert(ByVal aHandle As Long)
Dim Line As String
Line = "From " + SockLib.GetRemoteAddress(aHandle) + " at " + Format(Now, "hh:mm:ss") + Chr(13) + Chr(13)
Line = Line + SockLib.TextFromBuffer(aHandle)
Call ShowMessage(Line, "Alert")
End Sub
'A chat message is available
Private Sub HaveChat(ByVal aHandle As Long)
Dim Line As String
If txtChatLog.Text > "" Then
Line = Chr(13) + Chr(10)
End If
Line = Line + "[" + Format(Now, "hh:mm:ss") + "] Peer: "
Line = Line + SockLib.TextFromBuffer(aHandle)
' txtChatLog.Text = txtChatLog.Text + Line
txtChatLog.SelStart = Len(txtChatLog.Text)
txtChatLog.SelText = Line
End Sub
'Downloaded file header is coming
Private Sub HaveFileHead(ByVal aHandle As Long)
On Error Resume Next
If DownFile > 0 Then
'download is already in progress
Call SockLib.SendPacket(aHandle, pcBUSY_DOWNLOAD)
Exit Sub
End If
DownPath = App.Path + "\Download"
If Not DirExists(DownPath) Then
MkDir (DownPath)
End If
If Not DirExists(DownPath) Then
Call ShowMessage("Cannot create the directory " + DownPath, "Error")
Exit Sub
End If
DownName = SockLib.TextFromBuffer(aHandle)
DownSize = SockLib.IntegerFromBuffer(aHandle)
DownFile = FreeFile()
Open DownPath + "\" + DownName For Binary As DownFile
If Err <> 0 Then
txtDownload.Text = "Cannot open " + DownPath + "\" + DownName
Call SockLib.SendPacket(aHandle, pcSTOP_DOWNLOAD)
DownFile = 0
Exit Sub
End If
DownSock = aHandle
DownCount = 0
Call SockLib.SendPacket(aHandle, pcGIVE_FILE_BODY)
UpdateStatus
End Sub
'Uploaded file data must go
Private Sub GiveFileBody(ByVal aHandle As Long)
If UpFile = 0 Then Exit Sub
Dim L As Long
Dim VarBytes As Variant
Dim ArrBytes() As Byte
If UpCount >= UpSize Then
'the file is done
txtUpload.Text = UpName + " Done."
FinishUpload
Else
L = UpSize - UpCount
If L > SockLib.GetFreeRoom(UpSock) Then
L = SockLib.GetFreeRoom(UpSock)
End If
ReDim ArrBytes(L - 1)
Get UpFile, , ArrBytes
If Err <> 0 Then
Call ShowMessage("Error reading " + UpName, "Error")
Call SockLib.SendPacket(aHandle, pcSTOP_UPLOAD)
FinishUpload
Exit Sub
End If
VarBytes = ArrBytes
Call SockLib.BytesToBuffer(UpSock, VarBytes)
UpCount = UpCount + L
Call SockLib.SendPacket(UpSock, pcHAVE_FILE_BODY)
End If
End Sub
'Downloaded file data is available
Private Sub HaveFileBody(ByVal aHandle As Long)
If DownFile = 0 Then Exit Sub
Dim VarBytes As Variant
Dim ArrBytes() As Byte
VarBytes = SockLib.BytesFromBuffer(DownSock)
ArrBytes = VarBytes
Put DownFile, , ArrBytes
If Err <> 0 Then
txtDownload.Text = "Error writing to " + DownName
Call SockLib.SendPacket(aHandle, pcSTOP_DOWNLOAD)
FinishDownload
Exit Sub
End If
DownCount = DownCount + UBound(ArrBytes) + 1
If DownCount >= DownSize Then
'the file is done
txtDownload.Text = DownName + " Done."
FinishDownload
End If
End Sub
'Peer upload is canceled
Private Sub StopUpload()
txtDownload.Text = "Canceled"
FinishDownload
End Sub
'Peer download is canceled
Private Sub StopDownload()
txtUpload.Text = "Canceled"
FinishUpload
End Sub
'Not able to accept download
Private Sub BusyDownload()
FinishUpload
Call ShowMessage("The download channel is taken", "Error")
End Sub
'Upload is done
Private Sub FinishUpload()
If UpFile <> 0 Then
Close UpFile
End If
UpFile = 0
txtUpload.Enabled = True
UpdateStatus
End Sub
'Download is done
Private Sub FinishDownload()
If DownFile = 0 Then Exit Sub
Close DownFile
DownFile = 0
UpdateStatus
End Sub
Private Sub btnAbortDown_Click()
Call SockLib.SendPacket(DownSock, pcSTOP_DOWNLOAD)
FinishDownload
txtDownload.Text = "Canceled"
End Sub
Private Sub btnAbortUp_Click()
Call SockLib.SendPacket(UpSock, pcSTOP_UPLOAD)
FinishUpload
txtUpload.Text = "Canceled"
End Sub
Private Sub btnBrowse_Click()
On Error GoTo IsCanceled
OpenDlg.FileName = ""
OpenDlg.ShowOpen
txtUpload.Text = OpenDlg.FileName
UpdateStatus
IsCanceled:
End Sub
'*** Event handlers
'A chat message will be sent
Private Sub btnChat_Click()
Dim Line As String
Call SockLib.TextToBuffer(lvPeers.SelectedItem.Tag, txtChatMsg.Text) 'Store the message
Call SockLib.SendPacket(lvPeers.SelectedItem.Tag, pcCHAT) 'Send the chat message
Line = ""
If txtChatLog.Text > "" Then
Line = Chr(13) + Chr(10)
End If
Line = Line + "[" + Format(Now, "hh:mm:ss") + "] Me: " + txtChatMsg.Text
txtChatMsg.Text = ""
txtChatLog.Text = txtChatLog.Text + Line
End Sub
'An alert message will be sent
Private Sub btnAlert_Click()
Call SockLib.TextToBuffer(lvPeers.SelectedItem.Tag, txtAlertMsg.Text) 'Store the message
Call SockLib.SendPacket(lvPeers.SelectedItem.Tag, pcALERT) 'Send an alert message
txtAlertMsg.Text = ""
End Sub
'Modify the settings
Private Sub btnSettings_Click()
fSettings.Show 1, Me
If fSettings.Canceled Then Exit Sub
SetProperties
UpdateStatus
End Sub
'Initializations
Private Sub Form_Load()
CallHandle = 0
SetProperties
UpdateStatus
End Sub
'Terminate on form closing
Private Sub Form_Unload(Cancel As Integer)
End
End Sub
'A list view item is clicked
Private Sub lvPeers_ItemClick(ByVal Item As MSComctlLib.ListItem)
UpdateStatus
End Sub
'A new session is opened due to an incoming call
Private Sub SockLib_OnSessionInvoked(ByVal aHandle As Long)
Dim LI As ListItem
Set LI = lvPeers.ListItems.Add(, , SockLib.GetRemoteAddress(aHandle))
LI.SubItems(1) = SockLib.GetRemotePort(aHandle)
LI.SubItems(2) = Format(Now, "hh:mm:ss")
LI.Tag = aHandle
UpdateStatus
End Sub
'Successful call
Private Sub SockLib_OnSessionCreated(ByVal aHandle As Long)
Dim LI As ListItem
Set LI = lvPeers.ListItems.Add(, , SockLib.GetRemoteAddress(aHandle))
LI.SubItems(1) = SockLib.GetRemotePort(aHandle)
LI.SubItems(2) = Format(Now, "hh:mm:ss")
LI.Tag = aHandle
CallHandle = 0
If lvPeers.SelectedItem Is Nothing Then
lvPeers.SelectedItem = LI
End If
UpdateStatus
End Sub
'Unsuccessful call
Private Sub SockLib_OnSessionRejected(ByVal aHandle As Long)
CallHandle = 0
UpdateStatus
Call ShowMessage("Cannot connect to " + txtIP.Text + ":" + txtPort.Text, "Error")
End Sub
'The socket is disconnected
Private Sub SockLib_OnSessionClosed(ByVal aHandle As Long)
Dim i As Long
For i = 1 To lvPeers.ListItems.Count
If lvPeers.ListItems.Item(i).Tag = aHandle Then
lvPeers.ListItems.Remove (i)
End If
Next i
UpdateStatus
End Sub
'A new packet is available
Private Sub SockLib_OnPacketReceived(ByVal aHandle As Long)
Select Case SockLib.GetRcvdCmnd(aHandle)
Case pcALERT
Call HaveAlert(aHandle) 'alert message
Case pcCHAT
Call HaveChat(aHandle) 'chat message
Case pcHAVE_FILE_HEAD
Call HaveFileHead(aHandle)
Case pcGIVE_FILE_BODY
Call GiveFileBody(aHandle)
Case pcHAVE_FILE_BODY
Call HaveFileBody(aHandle)
Case pcSTOP_UPLOAD
Call StopUpload
Case pcSTOP_DOWNLOAD
Call StopDownload
End Select
End Sub
Private Sub SockLib_OnPacketSent(ByVal aHandle As Long)
If SockLib.GetSentCmnd(UpSock) = pcHAVE_FILE_BODY Then
GiveFileBody (aHandle)
End If
End Sub
'Show my IP address
Private Sub btnIP_Click()
Call ShowMessage(SockLib.IPAddress, "Information")
End Sub
'Terminate the application
Private Sub btnExit_Click()
End
End Sub
'Initiate a call
Private Sub btnConnect_Click()
'start the call operation
CallHandle = SockLib.CreateSession(txtIP.Text, Val(txtPort.Text))
If CallHandle = 0 Then
Call ShowMessage("Cannot initiate a call", "Error")
CallHandle = 0
End If
UpdateStatus
End Sub
'Cancel a call operation
Private Sub btnCancel_Click()
If CallHandle > 0 Then
SockLib.TerminateSession (CallHandle)
CallHandle = 0
UpdateStatus
End If
End Sub
'Remove the selected connection
Private Sub btnRemove_Click()
If lvPeers.SelectedItem Is Nothing Then
Exit Sub
End If
SockLib.TerminateSession (lvPeers.SelectedItem.Tag)
lvPeers.ListItems.Remove (lvPeers.SelectedItem.Index)
lvPeers.SelectedItem = Nothing
End Sub
'Update file transfer info
Private Sub Timer_Timer()
If UpFile > 0 Then
txtUpload.Text = UpName + " " + Str(UpCount) + "/" + Str(UpSize)
End If
If DownFile > 0 Then
txtDownload.Text = DownName + " " + Str(DownCount) + "/" + Str(DownSize)
End If
End Sub
'Hide the focus from the chat box
Private Sub txtChatLog_GotFocus()
helper.SetFocus
End Sub
Private Sub btnUpload_Click()
On Error Resume Next
If UpFile > 0 Then
' ShowMessage ("An uploading process is already in progress")
Call ShowMessage("An uploading process is already in progress", "My caption")
Exit Sub
End If
If txtUpload.Text = "" Then
Call ShowMessage("Please specify a file name", "Error")
Exit Sub
End If
UpSize = -1
UpSize = FileLen(txtUpload.Text)
If UpSize < 0 Then
Call ShowMessage("The file doesn't exist", "Error")
Exit Sub
End If
UpFile = FreeFile()
Open txtUpload.Text For Binary As UpFile
If Err <> 0 Then
Call ShowMessage("Cannot open the file", "Error")
UpFile = 0
Exit Sub
End If
UpCount = 0
UpSock = lvPeers.SelectedItem.Tag
UpName = ExtractFileName(txtUpload.Text)
Call SockLib.TextToBuffer(UpSock, UpName)
Call SockLib.IntegerToBuffer(UpSock, UpSize)
Call SockLib.SendPacket(UpSock, pcHAVE_FILE_HEAD)
UpdateStatus
txtUpload.Text = UpName + ": handshaking"
txtUpload.Enabled = False
End Sub
(c) BigSpeed Computing Inc. - Secure private networking