Imports System Imports System.Net Imports System.Net.Sockets Imports System.IO Imports System.Threading '-------- The following code is a modified version of a VB sample code "NetworkStreamSampleVBReceiver". --------' '---------------- The orginal script was downloaded from www.winsocketdotnetworkprogramming.com ----------------' '------------ The name of the process has changed from "NetworkStreamSampleVBReceiver" to SWAsrvapp ------------' ' This sample demonstrates how To use the NetworkStream Class To ' perform IO between 2 sockets. When using TCP Sockets you have to ' build a listening Socket application that will receive a connection ' from another application. In Socket terminology the application that ' receives a connection is know as a server and the peer that connects ' to a server is know as a client. ' ' The focus of this sample is not on Sockets but on network streams. We ' call this application a NetworkStreamServer because it is designed to ' receive a Socket connection and perform IO using a NetworkStream. ' ' To run this sample, simply just run the program without parameters and ' it will listen for a client connection on TCP port 5150. If you want to ' use a different port than 5150 then you can optionally supply a command ' line parameter "/port " and the listening socket will use ' your port instead. Module Module1 ' The main entry point for the application. Sub Main() Console.Title = "SWA Data Streamer on 2366 with starttime request" ' The following are default values, change accordingly Dim ServerName As String = "0.0.0.0" ' "127.0.0.1" Dim Port As Integer = 2366 ' 5150 Dim ClientAddress As String Dim ClientPort As Integer ' Specify a file to read from (MODIFIED) Dim pathSource As String ' Specify a file to write the report (MODIFIED) Dim reporttext As StreamWriter = My.Computer.FileSystem.OpenTextFileWriter("Reports\Recent\SWA_DataStreamerOnrequest_Report_" + System.DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ") + ".txt", False, System.Text.Encoding.ASCII) reporttext.AutoFlush = True Dim chosenfileid As Integer = -10 Dim intialfilelistarray() As String checkagainforthefirstfile: intialfilelistarray = createfilelist() pathSource = "" If intialfilelistarray.Length = 0 Then Console.ForegroundColor = ConsoleColor.Yellow '(MODIFIED) Console.Clear() Console.WriteLine("No cached data or live stream detected. Waiting for new data from the server! ") '(MODIFIED) reporttext.WriteLine("No cached data or live stream detected. Waiting for new data from the server! ") '(MODIFIED) Thread.Sleep(5000) GoTo checkagainforthefirstfile 'Console.ForegroundColor = ConsoleColor.White '(MODIFIED) 'reporttext.Close() 'Exit Sub End If Console.Clear() Dim ServerSocket As Socket = Nothing Dim ListeningSocket As Socket = Nothing Try ' Setup a listening Socket to await a connection from a peer socket. ListeningSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP) Dim ListeningEndPoint As IPEndPoint = New IPEndPoint(IPAddress.Parse(ServerName), Port) ListeningSocket.Bind(ListeningEndPoint) Console.ForegroundColor = ConsoleColor.Green '(MODIFIED) Console.WriteLine("Bind is OK!") '(MODIFIED) reporttext.WriteLine("Bind is OK!") '(MODIFIED) ListeningSocket.Listen(5) Console.WriteLine("Listen is OK!") '(MODIFIED) reporttext.WriteLine("Listen is OK!") '(MODIFIED) Console.ForegroundColor = ConsoleColor.Cyan '(MODIFIED) Console.WriteLine("Awaiting a TCP connection on IP: " + ListeningEndPoint.Address.ToString() + " Port: " + ListeningEndPoint.Port.ToString() + "...") reporttext.WriteLine("Awaiting a TCP connection on IP: " + ListeningEndPoint.Address.ToString() + " Port: " + ListeningEndPoint.Port.ToString() + "...") 'Console.WriteLine("Waiting for the client ro connect...") '(MODIFIED) ServerSocket = ListeningSocket.Accept() Console.ForegroundColor = ConsoleColor.Green '(MODIFIED) Console.WriteLine("Accept is OK!") '(MODIFIED) reporttext.WriteLine("Accept is OK!") '(MODIFIED) 'Dim proc As New System.Diagnostics.Process() '(MODIFIED) 'proc = Process.Start("SWA_datastreamer_onrequestLAUNCHER.bat", "") '(MODIFIED) Dim streamerLAUNCHERproc As New System.Diagnostics.Process() Dim streamerLAUNCHERprocinfo As New ProcessStartInfo("SWA_datastreamer_onrequestLAUNCHER.bat") streamerLAUNCHERprocinfo.WindowStyle = ProcessWindowStyle.Minimized streamerLAUNCHERproc = Process.Start(streamerLAUNCHERprocinfo) Dim Clientip As IPEndPoint = ServerSocket.RemoteEndPoint '(MODIFIED) ClientAddress = Clientip.Address.ToString ClientPort = Clientip.Port Console.ForegroundColor = ConsoleColor.Cyan '(MODIFIED) Console.WriteLine("Received a connection from IPaddress: " + CStr(ClientAddress) + " on port No.: " + CStr(ClientPort)) '(MODIFIED) reporttext.WriteLine("Received a connection from IPaddress: " + CStr(ClientAddress) + " on port No.: " + CStr(ClientPort)) '(MODIFIED) Catch e As SocketException Console.ForegroundColor = ConsoleColor.DarkRed '(MODIFIED) Console.WriteLine("Failure to create Sockets: " + e.Message) reporttext.WriteLine("Failure to create Sockets: " + e.Message) reporttext.Close() Exit Sub Finally ' Close the listening socket - we do not plan to handle any ' additional connections. ListeningSocket.Close() End Try '''''''''''.....................................................................................''''''''''' '''trying to read the timespan requested (the variables have "initial" tag in them) ''' Dim ServerNetworkStream As NetworkStream = Nothing Dim InitialBytestotext As String = "" Dim InitialBytestotext_date As String = "" Dim InitialBytestotext_time As String = "" Try Try ' Setup a network stream on the server Socket 'Console.WriteLine("Instantiate the reading NetworkStream object...") ServerNetworkStream = New NetworkStream(ServerSocket, True) Catch e As Exception Throw New Exception("Failed to create a Network Stream with error: " + e.Message) End Try Try Dim BytesInitialRead As Integer = 0 Dim ReadInitialBuffer(4096) As Byte 'Console.WriteLine("Reading...") 'Do BytesInitialRead = ServerNetworkStream.Read(ReadInitialBuffer, 0, ReadInitialBuffer.GetUpperBound(0)) 'Console.WriteLine("We read " + BytesInitialRead.ToString() + " byte(s) from a peer socket.") For i = 0 To BytesInitialRead - 1 InitialBytestotext += ChrW(CInt(ReadInitialBuffer(i).ToString())) 'Console.WriteLine("The byte #" + i.ToString() + " contains " + ReadInitialBuffer(i).ToString()) Next 'Console.WriteLine(InitialBytestotext) Dim requestedstartdate As String = "" Dim requestedstarttime As String = "" If Right(Left(InitialBytestotext, 9), 1) = "T" And Right(Left(InitialBytestotext, 16), 1) = "Z" Then '''''checks the validity of time/date format requestedstartdate = Left(InitialBytestotext, 8) requestedstarttime = Right(Left(InitialBytestotext, 15), 6) Console.ForegroundColor = ConsoleColor.White Console.WriteLine("") Console.WriteLine("StartDate: " & requestedstartdate) Console.WriteLine("StartTime: " & requestedstarttime) Console.WriteLine("") reporttext.WriteLine("") reporttext.WriteLine("StartDate: " & requestedstartdate) reporttext.WriteLine("StartTime: " & requestedstarttime) reporttext.WriteLine("") Else Console.ForegroundColor = ConsoleColor.Yellow '(MODIFIED) Console.WriteLine("The starting date/time format is not correct! Please enter it as yyyymmddThhmmssZ") '(MODIFIED) reporttext.WriteLine("The starting date/time format is not correct! Please enter it as yyyymmddThhmmssZ") '(MODIFIED) Console.ForegroundColor = ConsoleColor.White '(MODIFIED) reporttext.Close() Exit Sub End If ''''' does the selection to the nearest file intialfilelistarray = createfilelist() 'update the list of files Dim filenamedate As String = "" Dim filenametime As String = "" For iii = 0 To intialfilelistarray.Length - 1 'Console.WriteLine(Left(Right(intialfilelistarray(iii).ToString, 20), 16)) filenamedate = Left(Right(intialfilelistarray(iii).ToString, 20), 8) filenametime = Left(Right(intialfilelistarray(iii).ToString, 11), 6) 'Console.WriteLine(filenamedate + filenametime) 'Console.WriteLine(requestedstartdate + requestedstarttime) If CLng(filenamedate + filenametime) >= CLng(requestedstartdate + requestedstarttime) Then 'Console.WriteLine("true") chosenfileid = iii - 1 Exit For Else 'Console.WriteLine("False") End If Next ''''' 'Console.WriteLine(chosenfileid) If chosenfileid = -1 Then chosenfileid = 0 '''''if the requested time was before the oldest file, it will choose the oldest file anyway End If If chosenfileid = -10 Then chosenfileid = intialfilelistarray.Length - 1 '''''if the requested time was after the latest file, it will choose the latest file anyway End If 'Console.WriteLine(chosenfileid) InitialBytestotext = "" 'Loop Until BytesInitialRead > 0 Catch e As Exception Throw New Exception("Failed to read from a network stream with error: " + e.Message) End Try Catch e As Exception Console.WriteLine(e.Message) reporttext.WriteLine(e.Message) Finally ' We are finished with the NetworkStream, so we will close it. ' Note: the ServerSocket will be closed by the NetworkStream. '''''''ServerNetworkStream.Close() End Try '''''''''''.....................................................................................''''''''''' ' Let's create a network stream to communicate over the connected Socket. 'Dim ServerNetworkStream As NetworkStream = Nothing Dim bytecounter As Integer = 0 '(MODIFIED) Dim sizeofthelatestpacketinbytes As Integer = 0 Try Try ' Setup a network stream on the server Socket 'Console.ForegroundColor = ConsoleColor.Cyan '(MODIFIED) 'Console.WriteLine("Instantiate a NetworkStream object...") ServerNetworkStream = New NetworkStream(ServerSocket, True) Catch e As Exception Console.ForegroundColor = ConsoleColor.DarkRed '(MODIFIED) Throw New Exception("Failed to create a Network Stream with error: " + e.Message) End Try Try Dim Buffer(1) As Byte 'Console.ForegroundColor = ConsoleColor.Cyan '(MODIFIED) 'Console.WriteLine("Sending the buffered bytes...") '(MODIFIED) '---------------------------------------------------------------------------------------------------------------------------------------------' '-------- This part of the code was copy pasted from https://msdn.microsoft.com/en-us/library/system.io.filestream.read(v=vs.110).aspx--------' Dim totalbytesread As Integer = 0 Dim nonewpackettimer As Integer = 0 Dim sleeptime As Integer = 1000 ' in miliseconds Dim nonewpackettimeoute As Integer = 10 * 3600000 ' in miliseconds Dim streammode As String streammode = "cached" ' cached is when the files are being streamed, and it changes to live when streaming is from the latest file, which is being topped up by new bytes Console.ForegroundColor = ConsoleColor.Green Console.WriteLine(" ") Console.WriteLine("Client is connected!") Console.WriteLine(" ") reporttext.WriteLine(" ") reporttext.WriteLine("Client is connected!") reporttext.WriteLine(" ") Console.ForegroundColor = ConsoleColor.White Console.WriteLine("-----------------------------------------------------------------------") Console.Write(" Pktsize ") reporttext.WriteLine("-----------------------------------------------------------------------") reporttext.Write(" Pktsize ") Console.ForegroundColor = ConsoleColor.Cyan Console.Write(vbTab & "Streaming DateTime(UTC)") reporttext.Write(vbTab & "Streaming DateTime(UTC)") Console.ForegroundColor = ConsoleColor.Yellow Console.WriteLine(vbTab & "Pktsource") reporttext.WriteLine(vbTab & "Pktsource") Console.ForegroundColor = ConsoleColor.White Console.WriteLine("-----------------------------------------------------------------------") reporttext.WriteLine("-----------------------------------------------------------------------") streamtosocket: 'Check if the socket is still connected (Modified) Try Dim nullbuffer(0) As Byte ServerSocket.Send(nullbuffer, 0, 0) 'Console.WriteLine(" ServerSocket.Blocking.ToString()" + ServerSocket.Blocking.ToString()) Catch e As SocketException Throw New Exception("Client disconnected!") End Try ' 'Check how many files are created (maybe new ones are added) Dim filelistarray() As String filelistarray = createfilelist() Dim ii As Integer For ii = 0 To filelistarray.Length - 1 If (pathSource = filelistarray(ii)) And (ii < filelistarray.Length - 1) Then If streammode = "cached" Then pathSource = filelistarray(ii + 1) totalbytesread = 0 nonewpackettimer = 0 sleeptime = 1000 Console.ForegroundColor = ConsoleColor.Cyan Console.Write(vbTab & System.DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss")) reporttext.Write(vbTab & System.DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss")) Console.ForegroundColor = ConsoleColor.Yellow Console.Write(vbTab & "file No.{0} : " & Left(Right(filelistarray(ii).ToString, 20), 16), ii + 1) reporttext.Write(vbTab & "file No.{0} : " & Left(Right(filelistarray(ii).ToString, 20), 16), ii + 1) 'Console.WriteLine("Streaming cached file No. {0} ...", ii + 1) Exit For ElseIf streammode = "live" Then Console.WriteLine("") Console.WriteLine(vbTab & "New cache file created.") Console.Write(vbTab) reporttext.WriteLine("") reporttext.WriteLine(vbTab & "New cache file created.") reporttext.Write(vbTab) streammode = "cached" ' this is to make sure that last bits of the live stream from the the current streaming file is sent, before going to the next new file to stream Exit For End If Else If pathSource = "" Then pathSource = filelistarray(chosenfileid) 'instead of first file, it will chose the file based on the requested start date/time Exit For End If If (ii = filelistarray.Length - 1) And (nonewpackettimer <= sleeptime) Then Console.Write(vbTab & System.DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss")) reporttext.Write(vbTab & System.DateTime.UtcNow.ToString("yyyy/MM/dd HH:mm:ss")) Console.ForegroundColor = ConsoleColor.Yellow Console.Write(vbTab & "live...") reporttext.Write(vbTab & "live...") 'Console.WriteLine("Streaming live packets ...") sleeptime = 3000 streammode = "live" End If End If Next Try Using fsSource As FileStream = New FileStream(pathSource, FileMode.Open, FileAccess.Read, FileShare.ReadWrite) fsSource.Position = totalbytesread ' Read the source file into a byte array. Dim bytes() As Byte = New Byte((fsSource.Length) - 1) {} Dim numBytesToRead As Integer = CType(fsSource.Length, Integer) Dim numBytesRead As Integer = 0 numBytesToRead -= totalbytesread Dim initiallength As Long = fsSource.Length If numBytesToRead > 0 Then 'Console.WriteLine("Data packets consisting of {0} Bytes are being sent ... ", numBytesToRead.ToString) sizeofthelatestpacketinbytes = numBytesToRead nonewpackettimer = 0 ' rests the timeout timer to zero if new packet arrives End If While (numBytesToRead > 0) ' Read may return anything from 0 to numBytesToRead. Dim n As Integer = fsSource.Read(bytes, numBytesRead, numBytesToRead) ' Break when the end of the file is reached. If (n = 0) Then Exit While End If numBytesRead = (numBytesRead + n) numBytesToRead = (numBytesToRead - n) '''' ' send the byte array to the socket ' For i = 1 To n ' Buffer(0) = bytes(i - 1) 'ServerNetworkStream.Write(Buffer, 0, Buffer.GetUpperBound(0)) 'bytecounter += 1 '(MODIFIED) ' Next '''' ServerNetworkStream.Write(bytes, 0, numBytesRead) Console.ForegroundColor = ConsoleColor.White Console.WriteLine("") Console.Write(" {0} ", numBytesRead.ToString) reporttext.WriteLine("") reporttext.Write(" {0} ", numBytesRead.ToString) 'Console.WriteLine("{0} Bytes sent to IPaddress {1} ", numBytesRead.ToString, CStr(ClientAddress)) Console.ForegroundColor = ConsoleColor.Cyan End While numBytesToRead = bytes.Length totalbytesread = fsSource.Seek(0, SeekOrigin.Current) Thread.Sleep(sleeptime) nonewpackettimer += sleeptime 'If fsSource2.Length <> initiallength Then 'GoTo sendtosocket ' End If End Using Catch ioEx As FileNotFoundException Console.WriteLine(ioEx.Message) reporttext.WriteLine(ioEx.Message) End Try '---------------------------------------------------------------------------------------------------------------------------------------------' '---------------------------------------------------------------------------------------------------------------------------------------------' If nonewpackettimer < nonewpackettimeoute Then GoTo streamtosocket Else Console.ForegroundColor = ConsoleColor.Yellow '(MODIFIED) Console.WriteLine("Timeout!") Console.WriteLine("No new incoming packets for " + CStr(Math.Floor(nonewpackettimer / 60000)) + " minute(s) and " + CStr((nonewpackettimer / 60000 - Math.Floor(nonewpackettimer / 60000)) * 60) + " second(s).") '(MODIFIED) reporttext.WriteLine("Timeout!") reporttext.WriteLine("No new incoming packets for " + CStr(Math.Floor(nonewpackettimer / 60000)) + " minute(s) and " + CStr((nonewpackettimer / 60000 - Math.Floor(nonewpackettimer / 60000)) * 60) + " second(s).") '(MODIFIED) End If Console.ForegroundColor = ConsoleColor.Yellow '(MODIFIED) Console.WriteLine("We sent " + CStr(bytecounter) + " bytes to IPaddress: " + CStr(ClientAddress)) '(MODIFIED) reporttext.WriteLine("We sent " + CStr(bytecounter) + " bytes to IPaddress: " + CStr(ClientAddress)) '(MODIFIED) Console.ForegroundColor = ConsoleColor.Green '(MODIFIED) Console.WriteLine("Transfer completed.") '(MODIFIED) reporttext.WriteLine("Transfer completed.") '(MODIFIED) Catch e As Exception ServerNetworkStream.Close() Console.ForegroundColor = ConsoleColor.Yellow '(MODIFIED) Console.WriteLine("We sent " + CStr(bytecounter - sizeofthelatestpacketinbytes) + " bytes to IPaddress: " + CStr(ClientAddress)) '(MODIFIED) reporttext.WriteLine("We sent " + CStr(bytecounter - sizeofthelatestpacketinbytes) + " bytes to IPaddress: " + CStr(ClientAddress)) '(MODIFIED) Console.ForegroundColor = ConsoleColor.Red '(MODIFIED) Throw New Exception("Failed to send NetworkStream with error: " + e.Message) End Try Catch e As Exception Console.ForegroundColor = ConsoleColor.Red Console.WriteLine(e.Message) reporttext.WriteLine(e.Message) Finally ' We are finished with the NetworkStream, so we will close it. ' Note: the ServerSocket will be closed by the NetworkStream. ServerNetworkStream.Close() End Try Console.ForegroundColor = ConsoleColor.White End Sub Function createfilelist() '-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------' '-------- This part of the code was copy pasted from https://docs.microsoft.com/en-us/dotnet/api/microsoft.visualbasic.myservices.filesystemproxy.getfiles?view=netframework-4.7.1--------' Dim foundfilecounter As Integer = 0 For Each foundFile As String In My.Computer.FileSystem.GetFiles( My.Computer.FileSystem.CurrentDirectory, FileIO.SearchOption.SearchTopLevelOnly, "Data\Recent\IncomingSWAdata_*.dat") foundfilecounter += 1 Next Dim foundfilearray(foundfilecounter - 1) As String foundfilecounter = 0 For Each foundFile As String In My.Computer.FileSystem.GetFiles( My.Computer.FileSystem.CurrentDirectory, FileIO.SearchOption.SearchTopLevelOnly, "Data\Recent\IncomingSWAdata_*.dat") foundfilearray(foundfilecounter) = foundFile foundfilecounter += 1 Next '-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------' '-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------' Return foundfilearray End Function End Module