I have the following code as part of TCP server
Private Sub StartTcpClient(ByVal client As TcpClient)
Dim bytesRead As Integer
Dim RxBuffer(1024) As Byte
Dim RxDataStr As String = ""
Dim BeginTime As Date = Date.Now
Dim CurrentTime As Date
Dim ElapsedTicks As Long = -1
'Dim elapsedSpan As New TimeSpan(elapsedTicks)
While True
bytesRead = client.GetStream.Read(RxBuffer, 0, RxBuffer.Length)'What happen here?
If bytesRead > 0 Or ElapsedTicks < 3 * 10000000.0 Then 'Espera hasta 3 segundos
CurrentTime = Date.Now
ElapsedTicks = CurrentTime.Ticks - BeginTime.Ticks
'RxDataStr = System.Text.ASCIIEncoding.ASCII.GetString(RxBuffer, 0, bytesRead) 'Original
RxDataStr += System.Text.ASCIIEncoding.Default.GetString(RxBuffer, 0, bytesRead) 'UTF8
Else
client.Close()
AckString = RxDataStr
AckReady = True
AckPending = False
Exit Sub
End If
End While
End Sub
I wonder about what happen when the line GetStream.Read is executed.
It goes away from my code and doesn't come back until some data is collected or an error happens or something else?
What I need to do is close the current connection if the time between the data arrivals is bigger than 3 seconds.
It appears that you are trying to read from a stream in a loop until no more data is received, or a certain amount of time has passed since you started reading.
The call you use to do this Stream.Read is a blocking call. So if you don't receive any data, this will block indefinitely.
Because in your case, the the stream instance you have is a NetworkStream, you can specify its ReadTimeout property to prevent this. This causes the following behavior:
If the read operation does not complete within the time specified by
this property, the read operation throws an IOException.
Thus, you will have to catch the IOException and check if it is due to a read timeout. Your code would then look like this:
Imports System.Diagnostics
// ... other stuff
Dim stream As Stream = client.GetStream
Dim maxTime As TimeSpan = TimeSpan.FromSeconds(3)
Dim elapsed As Stopwatch = Stopwatch.StartNew()
Dim done As Boolean = False
While Not done
Dim timeout As Long = CLng((maxTime - elapsed.Elapsed).TotalMilliseconds))
If (timeout > 0) Then
stream.ReadTimeout = timeout
Try
bytesRead = stream.Read(RxBuffer, 0, RxBuffer.Length)
If bytesRead > 0 Then 'Espera hasta 3 segundos
RxDataStr += System.Text.ASCIIEncoding.Default.GetString(RxBuffer, 0, bytesRead) 'UTF8
Else
done = True
End If
Catch ioEx As IOException
If elapsed.Elapsed > maxTime Then
done = True ' due to read timeout
Else
Throw ' not due to read timeout, rethrow
End If
End Try
Else
done = True
End If
End While
client.Close()
AckString = RxDataStr
AckReady = True
AckPending = False
Since you are doing I/O, I would also recommend performing it as an asynchronous operation using async/await and Stream.ReadAsync. In this case you should make all the methods in your call chain do async/await.
Related
I am reading a SSE by using this method
Public Shared Sub ReadStreamForever(ByVal stream As Stream)
Dim encoder = New UTF8Encoding()
Dim buffer = New Byte(2047) {}
Dim counter As Integer = 0
While True
If stream.CanRead Then
Dim len As Integer = stream.Read(buffer, 0, 2048)
counter = counter + 1
If len > 0 Then
Dim text = encoder.GetString(buffer, 0, len)
SSEApplication.Push(text) 'Here I collect the text slices to a List(of string) object
Else
Exit While
End If
Else
Exit While
End If
End While
SSEApplication.writer() 'Here I write the content to a .txt file
End Sub
With my example data it takes about 2 seconds. I would prefer not to read the stream into memory though and tried this method
Public Shared Sub ReadStreamForever1(ByVal stream As Stream)
Dim output As FileStream = File.OpenWrite("C:\Users\mini_dataset.txt")
While True
If stream.CanRead Then
stream.CopyTo(output)
Else
Exit While
End If
End While
End Sub
But the process ends up in an endless loop (I guess) at least to me it looks like the end of the stream can not be found. I can break the process after a few seconds and all the data are in the .txt file. Any idea what I can do to get the direct stream to file method working?
Stream.CanRead tells you whether a stream supports reading. Since it's apparently readable, While True will go on forever.
Let's verify whether the output Stream.CanWrite instead.
Public Shared Sub ReadStreamForever1(ByVal stream As Stream)
Using output As FileStream = File.OpenWrite("[Output file path]")
If output.CanWrite Then
stream.CopyTo(output)
End If
End Using
End Sub
If the process takes some time and you need to report its progress, you could read the stream using a buffer (I didn't add any error checking but of course a try/catch block should be used):
(Here, with 100 parts division commonly used by a ProgressBar)
Public Sub ReadStreamForever1(ByVal stream As Stream)
Dim BufferLength As Integer = 81920 'As the default stream buffer
Dim Buffer(BufferLength) As Byte
Dim BytesRead As Long = 0L
Using output As FileStream = File.OpenWrite("[Output file path]")
If output.CanWrite Then
Dim Part As Long = stream.Length \ 100
Dim PartCount As Integer = 0
Dim read As Integer = 0
Do
read = stream.Read(Buffer, 0, BufferLength)
If read = 0 Then Exit Do
If (BytesRead / Part > PartCount) Then
PartCount += 1
'ReportWriteProgress(PartCount)
End If
output.Write(Buffer, 0, read)
BytesRead += read
Loop
End If
End Using
End Sub
I have an application that currently runs a ping against about 60 different gateways to monitor internet uptime for my clients as I want to know if their internet drops out before they do. So currently my application runs through a loop starting at the first one (runs 4 pings) waits 2 seconds and then moves on to the next gateway address. I have then implemented some code to retry a number of times if the ping results as a failure as I want to be 100% sure that their connection is down before sending an alert.
The problem with this method is that it takes around 1 or 2 minutes (or sometimes longer) before the same gateway is scanned again, meaning that if the connection was to drop out straight after a ping, I wouldn't know for nearly 2 minutes. I know this sounds miniscule but I would much rather instant alerting to my team so they can act on this immediately.
Therefore, my question is: Would it be better (and what would be the impact) of running 60 separate pings (on different threads maybe) instead of cycling through each one. This way I could run a continuous ping on each gateway at the same time. However, I am worried about performance impact on my application and if it will create too much load on the system.
Any advice would be appreciated. Thanks
EDIT
I have created the following code which works but seems to impact a single processor core heavily and whilst this method works without error, it seems to deem the GUI as in-responsive soon after:
Public Sub PingHost()
Try
GatewayScanning = True
For i As Integer = 0 To Gateways.Count - 1
Dim t As New Threading.Thread(AddressOf CheckHostOnline)
t.IsBackground = True
t.Start(Gateways(i))
Next
Catch ex As Exception
ErrorTrap(ex, "OfflineClientHandler: PingHost()")
End Try
End Sub
Public Sub CheckHostOnline(ByVal gw As Object)
Try
Dim _gateway As Gateway_Object = DirectCast(gw, Gateway_Object)
Dim pingSender As New Ping()
Dim options As New PingOptions()
'Dim averageTime As Integer
Dim OfflinePingCount As Integer = 0
' Use the default Ttl value which is 128,
' but change the fragmentation behavior.
options.DontFragment = False
options.Ttl = 128
' Create a buffer of 32 bytes of data to be transmitted.
Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Dim buffer() As Byte = Encoding.ASCII.GetBytes(data)
Dim timeout As Integer = 3000
Do While Not GatewayScanning = False
Dim reply As PingReply = pingSender.Send(_gateway.Gateway, timeout, buffer, options)
If reply.Status = IPStatus.Success Then
Dim resultTime As Integer = GetMs(CInt(reply.RoundtripTime))
_gateway.Status = "ONLINE"
_gateway.Result = resultTime
Else
OfflinePingCount += 1
If OfflinePingCount < (My.Settings.OfflinePingCycleNumber * 4) Then
_gateway.Status = "TIMEOUT"
_gateway.Result = -1
Else
_gateway.Status = "OFFLINE"
_gateway.Result = -1
End If
End If
SyncLock class_OfflineGateways
class_OfflineGateways.UpdateListView(_gateway)
End SyncLock
System.Threading.Thread.Sleep(2000)
Loop
pingSender.Dispose()
Catch ex As Exception
ErrorTrap(ex, "OfflineClientHandler: CheckHostOnline()")
End Try
End Sub
One way to do this is to cycle through the 60 IPs on different threads, and require a five-second (or some amount of time) delay before beginning the cycle again.
Another way is to us asynchronous pings instead of separate threads.
Last time I did this, I ended up using a single thread with 10 ms sleep delay between pings. There were too many ping failures whenever I bunched them together, either with threads or asynch pings. I never did figure out whether the problem was on the server end or on the destination network.
Here's a class I used to ping a list of IP addresses. It (and a bunch of other stuff) ran as a service on an ISP server. (I notice I still have the backgroundworker declared, although it's no longer used.)
Imports System.Net
Imports System.Threading
Imports System.Collections.Generic
Class pingGroup
' used to ping each IP in Targets
Public Targets As New List(Of IPAddress)
Public sectorID As Integer
Public nErrors As Integer = 0
Public Timeout As Integer = pingTimeout
Public PingLog As New List(Of String)
Public PingAvg As Integer = -2 ' -2 = uninit, -1 = error, else average ms excluding the slowest
Public PingTime As DateTime
Public pingCount As Integer = 0
Public pingStarts As Integer = 0
Dim msTotal As Integer = 0
Dim WithEvents bkgPing As System.ComponentModel.BackgroundWorker
Public Sub New(ByVal groupSectorID As Integer)
sectorID = groupSectorID
End Sub
Public Sub Ping()
' run a pingtest once, adding the result incrementally
Dim ip As IPAddress
Dim reply As NetworkInformation.PingReply
Dim ms As Integer
PingTime = Now
If PingLog.Count <= 0 Then PingLog.Add(Format(Now, "G") & " Ping Test")
For Each ip In Targets
Using pPing As New NetworkInformation.Ping
Try
pingStarts = pingStarts + 1
reply = pPing.Send(ip, Timeout)
If reply.Status = NetworkInformation.IPStatus.Success Then
ms = reply.RoundtripTime
pingCount = pingCount + 1
msTotal = msTotal + ms
If pingCount > 0 Then PingAvg = msTotal / pingCount
PingLog.Add(reply.Address.ToString & " " & ms)
Else
nErrors = nErrors + 1
PingLog.Add(Format(Now, "G") & " ---Ping Error: " & ip.ToString & " " & reply.Status.ToString)
End If
Catch ex As Exception
nErrors = nErrors + 1
PingLog.Add(Format(Now, "G") & " ===Ping Error: " & ip.ToString & " " & ex.Message)
End Try
End Using
Thread.Sleep(10)
Next ip
End Sub
End Class
I use VB.net 2008 to make a memory scanner and hacking program. I try some of their answers but still the memory scanner is slow. Maybe I have an improvement because before I scan a simple minesweeper and it takes 10 to 20 minutes. But now I can scan it for 2 to 10 seconds.
But I'm still not satisfied because when I try it in other games it takes 5 to 10 minutes or sometimes freeze due of too much long and too much usage of CPU.
Here is my code
Assume I declare all the API and some arguments for making a first scan
this code is a sample of scanning a 4 bytes address:
'' Command Button Event
btn_firstScan(....) Handle....
'' The Code
Me.Enabled = False
FirstScanThread = New Thread(AddressOf scanF)
FirstScanThread.IsBackground = True
FirstScanThread.Priority = ThreadPriority.Highest
FirstScanThread.Start() '' Thread Started for the First Scan.
End sub
Private Sub scanF() '' This is the Function is being Executed by the FirstScanThread at the btn_firstScan.
FirstScan(Of Int32)(pHandle, &H400000, &H7FFF0000, CType(txt_value.Text, Int32))
End Sub
The Sub FirstScan Executed by Sub scanF() that is being Executed by FirstScanThread in Command button btn_firstScan sub
Friend Sub FirstScan(Of T)(ByVal pHandle As IntPtr, ByVal minAddress As Int64, ByVal maxAddress As Int64, _
ByVal VALUE As T, Optional ByVal tempFileName As String = "temp.txt")
Dim thr As New Thread(AddressOf getProcessMemoryInfo) '' Get the Process Memory Info First
Dim memRange As New scanRange
memRange.minimum_address = minAddress
memRange.maximum_address = maxAddress
thr.IsBackground = True
thr.Priority = ThreadPriority.Highest
thr.Start(memRange)
thr.Join()
thr = New Thread(AddressOf dumpReadProcessMemory) '' Read All Bytes and Dump to the Temporary File
thr.IsBackground = True
thr.Priority = ThreadPriority.Highest
thr.Start()
thr.Join()
thr = New Thread(AddressOf readTempFile) '' Scan the Dump File in a Specific Set of Bytes [4 Bytes Aligned]
thr.IsBackground = True
thr.Priority = ThreadPriority.Highest
thr.Start(VALUE)
thr.Join()
setControlState(Me, True) '' If the Scan is Complete , The form is Ready Again to Receive Input
End Sub
Friend Sub dumpReadProcessMemory() '' This Sub is Use to Dump the All Bytes Read by ReadProcessMemory
Dim INFO As FileStream = New FileStream("FIRST.INFO.txt", FileMode.Open, FileAccess.Read, FileShare.Read)
Dim SR As StreamReader = New StreamReader(INFO) '' This is use to Obtain the Info that is needed to switch Page by Page Faster , No need to obtain in VirtualQueryEx
Dim BFILE As FileStream = New FileStream("FIRST.SCAN.txt", FileMode.Create, FileAccess.Write, FileShare.Write)
Dim BW As BinaryWriter = New BinaryWriter(BFILE) '' This is the Binary Writer for writing the READ Bytes
Dim BUFFER(0 To (1048576 * 128)) As Byte
Dim mem As New memoryInfo
While Not SR.EndOfStream '' While there is Page Found
mem.regionBaseAddress = CLng(SR.ReadLine.ToString)
mem.regionSize = CLng(SR.ReadLine.ToString)
ReadProcessMemory(pHandle, mem.regionBaseAddress, BUFFER, mem.regionSize, 0)
BW.Write(BUFFER, 0, mem.regionSize)
Thread.Sleep(1)
End While
SR.Close()
SR.Dispose()
INFO.Close()
INFO.Dispose()
BW.Close()
BFILE.Close()
BFILE.Dispose()
GC.Collect() '' Collect Garbage of BUFFER prevent CPU Stressing and RAM Leak, and i think i helps :P
End Sub
Friend Sub getProcessMemoryInfo(ByVal Obj As Object) '' Use to Get What PAGE is Readable/Writable and its Size
Dim FILE As System.IO.FileStream = New System.IO.FileStream("FIRST.INFO.txt", IO.FileMode.Create, FileAccess.Write, IO.FileShare.Write)
Dim SW As System.IO.StreamWriter = New System.IO.StreamWriter(FILE)
Dim BASE_ADDRESS As Int64 = CLng(Obj.minimum_address.ToString)
Dim MAX As Int64 = CLng(Obj.maximum_address.ToString)
Dim PAGE_COUNT As Integer = 0
While VirtualQueryEx(pHandle, BASE_ADDRESS, MBI, MBIsize)
If MBI.State = MemoryAllocationState.Commit Then
If MBI.zType = MemoryAllocationType.MEM_PRIVATE Or MBI.zType = MemoryAllocationType.MEM_IMAGE Then
Select Case MBI.AllocationProtect
'' Check if The Region is Readable/Writable and Executable
Case MemoryAllocationProtectionType.PAGE_CANWRITE
GoTo WRITE_INFO
Case MemoryAllocationProtectionType.PAGE_EXECUTE_READWRITE
GoTo WRITE_INFO
Case MemoryAllocationProtectionType.PAGE_WRITECOMBINE
GoTo WRITE_INFO
Case MemoryAllocationProtectionType.PAGE_EXECUTE_WRITECOPY
GoTo WRITE_INFO
Case MemoryAllocationProtectionType.PAGE_READWRITE
GoTo WRITE_INFO
Case Else
GoTo BYPASS_WRITE
End Select
WRITE_INFO:
SW.WriteLine(BASE_ADDRESS)
SW.WriteLine(MBI.RegionSize.ToInt32)
Thread.Sleep(1)
'PAGE_COUNT += 1
End If
End If
BYPASS_WRITE:
BASE_ADDRESS = BASE_ADDRESS + MBI.RegionSize.ToInt32
updateProgressTo(Me.pb_scanProgress, CInt(BASE_ADDRESS / MAX * 100))
End While
SW.Close()
SW.Dispose()
FILE.Close()
FILE.Close()
'Console.WriteLine(PAGE_COUNT)
End Sub
Public Sub readTempFile(ByVal Value As Object)
Dim TEMP As System.IO.FileStream = New System.IO.FileStream("TEMP.txt", IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.Write)
Dim TFILE As System.IO.FileStream = New System.IO.FileStream("FIRST.INFO.txt", IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim BFILE As System.IO.FileStream = New System.IO.FileStream("FIRST.SCAN.txt", IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.Read)
Dim SW As System.IO.StreamWriter = New System.IO.StreamWriter(TEMP) '' Will Contain a list of Addressed found with the Value input.
Dim SR As System.IO.StreamReader = New System.IO.StreamReader(TFILE) '' Contains the Region baseAddesses and Size
Dim BR As System.IO.BinaryReader = New System.IO.BinaryReader(BFILE) '' Contains the Bytes being Dump Before and will now Read for Scanning.
Dim ADDRESS_POINTER As Int64 = 0
Dim mem As New memoryInfo
Dim TEMP_BYTE(0 To 4 - 1) As Byte
Dim BUFFER(0 To (1024 * 1024)) As Byte = 1024KB
Dim BUFFER_INDEX = 0
mem.regionBaseAddress = CLng(SR.ReadLine.ToString) ''Obtain the Staring Base Address
mem.regionSize = CLng(SR.ReadLine.ToString) '' Obtain the Region Size
ADDRESS_POINTER = mem.regionBaseAddress
While BR.Read(BUFFER, 0, BUFFER.Length) '' Fill the BUFFER with Data
BUFFER_INDEX = 0
While BUFFER_INDEX < BUFFER.Length - (4 - 1)
For a As Integer = 0 To (4 - 1) '' Compile the Read Bytes
TEMP_BYTE(a) = BUFFER(BUFFER_INDEX + a)
Next
If BitConverter.ToInt32(TEMP_BYTE, 0) = Value Then '' If the Compiled 4 Bytes = Value then
SW.WriteLine(formatHex(Hex(ADDRESS_POINTER).ToString))
'addItemTo(Me.lb_addressList, formatHex(Hex(ADDRESS_POINTER).ToString))
End If
ADDRESS_POINTER += 4
BUFFER_INDEX += 1
mem.regionSize -= 4
If mem.regionSize <= 0 Then
If SR.EndOfStream Then
Exit While
Else
''Switch to the Next Region
mem.regionBaseAddress = CLng(SR.ReadLine.ToString) ''Obtain the Staring Base Address
mem.regionSize = CLng(SR.ReadLine.ToString) '' Obtain the Region Size
ADDRESS_POINTER = mem.regionBaseAddress
End If
End If
End While
Thread.Sleep(1) '' Prevent 100% CPU Usage therefore the Form and other App avoid Crashing and Not Responding,
End While
BR.Close()
BFILE.Close()
SW.Close()
TEMP.Close()
SW.Dispose()
TEMP.Dispose()
SR.Close()
SR.Dispose()
TFILE.Dispose()
GC.Collect()
setControlState(Me, True) '' Make the Form Enabled
End Sub
NOTE: formatHex is only a Function that will put trailing Zeros in the front of Hex String if the Hex is not have Length of 8.
This code works in minesweeper in Windows XP 32 Bit and works fast in MINESWEEPER ONLY. I tried it in Grand Chase and Farm Frenzy; the scan won't ends because its still slow and even the scan is done, there is no address being found (maybe because in just tested it for 4 bytes).
I like to use VirtualProtectEx and VirtualAllocEx to enable to scan those PAGE_GUARD and write on it. Therefore I am able to obtain the specific address that I want but I can't do it because it is still slow. I make the PAGE_GUARD'ed PAGE into EXECUTE_READWRITE it will make more bytes to scan. It will make the App slower.
I'm trying to create a TCP/IP Listener in Visual Basic. The Listener needs to be able to handle many different clients connecting at any given time. The code I've developed seems to work using the
socket.BeginAcceptSocket()
method. As from most of the examples I've seen, I listen for a new connection, receive it, process it, stop accepting on that socket, process the data, then close the connection. The threads I spawn in order to handle the recieving and processing of data close correctly and things are taken care of.
However, for some reason I seem to be getting an infinite number of threads that get created for my BeginAcceptSocket method. This causes my computer to slow down and eventually just lock up and I start missing data from the clients and etc etc.. I'll post my code below here, but basically is there something obvious I'm doing wrong here? I've spent quiet a bit of time searching around and trying to debug this and I'm quite stuck.
Imports System.Net.Sockets, System.Threading, System.IO, System.Net
Imports System.Text
Imports System.Data, System.Data.SqlClient
Module Module1
'The Tcp listener listening on port 2012
Dim listener As New TcpListener(IPAddress.Any, 2012)
'Signal for when to start listening on a new socket for a client
Private clientConnected As New ManualResetEvent(False)
'The threads being used for the processing
Private listenThread, test As Thread
Sub Main()
listener.Start()
listenThread = New Thread(AddressOf doListen)
listenThread.IsBackground = True
listenThread.Start()
Do
Select Case Console.ReadLine().ToLower
Case "exit"
Exit Do
End Select
Loop
End Sub
Sub message(ByVal msg As String)
msg.Trim()
Console.WriteLine(">> " + msg)
End Sub
Sub doListen()
'Reset the signal
clientConnected.Reset()
Do
'Start listening for new Sockets, upon a new socket create a new thread # AcceptClients
listener.BeginAcceptSocket(New AsyncCallback(AddressOf AcceptClients), listener)
'Wait for the new socket to be handled
clientConnected.WaitOne()
'Reset the flag and then repeat
clientConnected.Reset()
Loop
End Sub
Sub AcceptClients(ar As IAsyncResult)
'Get the listener that handles the request
Dim listen As TcpListener = CType(ar.AsyncState, TcpListener)
'Create a new socket and end the listening on that socket
Dim clientSocket As Socket = listen.EndAcceptSocket(ar)
'Notify the main thread that it is ready to listen for new connections
clientConnected.Set()
'Define variables used for lisetning and parsing messages
Dim byteRec(1024) As Byte
Dim message As String = Nothing
Dim N, C As Integer
Dim lengthFound As Boolean = False
Dim finished As Boolean = False
Do
Try
Dim intBytes As Int32 = clientSocket.Receive(byteRec, 0, clientSocket.Available,
SocketFlags.None)
message = ASCIIEncoding.ASCII.GetString(byteRec, 0, intBytes)
If intBytes > 0 Then ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf printMsg), message)
'If message.Contains(Chr(1)) And Not lengthFound Then
' 'Call method to return the total number of messages in the group
' N = getNumber(message, message.IndexOf(Chr(1)) + 1)
' lengthFound = True
'End If
'C = getCountOfMessages(message)
'If getCountOfMessages(message) = N And lengthFound Then
' finished = True
' Exit Do
'End If
While intBytes > 0 And Not finished
intBytes = clientSocket.Receive(byteRec, 0, clientSocket.Available, SocketFlags.None)
message = ASCIIEncoding.ASCII.GetString(byteRec, 0, intBytes)
'Somehow need to look for the number of STX's and increment the counter by each number
'C = getCountOfMessages(message)
'If message.Contains(Chr(1)) And Not lengthFound Then
' 'Call method to return the total number of messages in the group
' N = getNumber(message, message.IndexOf(Chr(1)) + 1)
' lengthFound = True
'End If
'If getCountOfMessages(message) = N And lengthFound Then
' finished = True
' Exit Do
'End If
End While
Catch ex As Exception
End Try
Loop
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf printMsg), message)
clientSocket.Close()
clientSocket.Dispose()
End Sub
'Method to return the total number of messages RECEIVED from a group
Function getCountOfMessages(ByVal message As String)
Dim C As Integer = 0
C = message.Split(Chr(2)).Count - 1
Return C
End Function
'Method to return the total number of messages in a group. Paramters are the total message string and the index of the SOH char
Function getNumber(ByVal message As String, ByVal index As Integer)
Dim N As Integer = 0
'Create a loop to start at the SOH and convert all data between SOH and ETX to N as an integer and return it
Dim S As Boolean = True
Dim temp As String = ""
While S
Select Case message(index)
Case Chr(3)
'End of message is found, exit loop
S = False
Case Else
'Add the data between the SOH and ETX to a string. Once finished convert the data to an int
' The reason I think this is neccessary would be in case we decide to have more than 9 messages, aka 2 or more digit numbers. like 10 or 300 etc..
temp = temp + message(index)
End Select
index = index + 1
End While
N = Convert.ToInt32(temp)
Return N
End Function
'This method will be used to reorder, parse and delimt the messages then add them into the SQL database
Sub printMsg(ByVal msg As Object)
Dim dataStr As String = ""
Debug.Print(msg & vbCrLf)
End Sub
End Module
Any help is greatly appreciated.
How Many Client can send data parallel? What Type Data send by client? After Receive Client Sent,Do you run some process? just make sure.
i make function that convert time string ("hh\:mm\:ss\,fff" - example:"00:00:00,100") to parts
strTime = "00:00:00,100" =
h int = 0
m int = 0
sec int = 0
millisec int = 100
The function:
Public Function ShowInLabel(ByVal TEXT As String, ByVal time As String, ByVal startTime As Boolean) As Boolean
On Error Resume Next
Dim sss As String
sss = time
Dim start As String = StrReverse(sss)
start = StrReverse(start.Substring(0, 3))
Dim s As Integer
s = Integer.Parse(start)
Dim secstart As String = StrReverse(sss).Substring(0, 6)
secstart = StrReverse(secstart)
Dim secs As Integer = Integer.Parse(secstart.Substring(0, 2))
Dim hurs As Integer = Integer.Parse(sss.Substring(0, 2))
Dim mins As Integer = Integer.Parse(StrReverse(StrReverse(sss.Substring(0, 5)).Substring(0, 2)))
Dim stopWatch As New Stopwatch()
stopWatch.Start()
noh:
If stopWatch.Elapsed.Hours = hurs Then
GoTo yesh
Else
GoTo noh
End If
yesh:
If stopWatch.Elapsed.Minutes = mins Then
GoTo yesm
Else
GoTo yesh
End If
yesm:
If stopWatch.Elapsed.Seconds = secs Then
GoTo yess
Else
GoTo yesm
End If
yess:
If stopWatch.Elapsed.Milliseconds > s Or stopWatch.Elapsed.Milliseconds = s Then
GoTo done
Else
GoTo yess
End If
done:
If startTime = False Then
Label1.Text = ""
Else
Label1.Text = TEXT
End If
Return True
End Function
example:
ShowInLabel("SubTitle", "00:00:00,100", True)
The Function Works ,
but when the function runing the application is Stucked Till the function return true
Why it happening?
All you need to do is something like this:
Dim time As Date = DateTime.ParseExact("00:01:02,123", "hh:mm:ss,fff", CultureInfo.InvariantCulture)
Dim h As Integer = time.Hour
Dim m As Integer = time.Minute
Dim sec As Integer = time.Second
Dim millisec As Integer = time.Millisecond
However, being all to familiar with what you're trying to accomplish :), I suspect what you really need is this:
Dim time As Date = DateTime.ParseExact("00:01:02,123", "hh:mm:ss,fff", CultureInfo.InvariantCulture)
Dim startTime As Date = DateTime.ParseExact("00:00:00,000", "hh:mm:ss,fff", CultureInfo.InvariantCulture)
Dim elapsed As TimeSpan = time - startTime
Dim totalMilliseconds As Integer = CType(elapsed.TotalMilliseconds, Integer)
You could, in the same way, convert the start and end times for each subtitle to total milliseconds and then compare them that way.
As others have pointed out, On Error Resume Next is only really available in VB.NET for backwards compatibility with VB6 code. You should use a Try/Catch block, instead. However, just putting a resume next above your entire method was never considered good practice, even in VB6, just as putting a try/catch block around the entire method would also be considered a bad idea.
Similarly, GoTo is just about the most terrible thing you could ever do by just about any programmer's sensibilities. You should consider other options such as loops, if/else blocks, breaking the code up into separate methods, etc., and avoid GoTo's at all costs.