I have no other plans of making VB.Net examples, so study this one carefully to get a feel for how to port C# code to VB.Net code. There might be small logic errors due to the porting process, but simple testing indicates it seems to work. I only spent enough time on this to port the code and get it working, I'm not comfortable with the VB.Net language, so my time here is really short. please don't ask me how you do things in VB.Net, I just Google'd everything.
Create a VB.Net Console project.
To add the "SilkroadSecurityApi.dll" as a reference:
1. Double click "My Project" (under the Solution Explorer on the right side of the screen)
2. Select "References" tab
3. Click Add
4. Choose "Browse"
5. Select the "SilkroadSecurityApi.dll" file and click OK
Now you can create a new code file and paste this in and edit it as needed.
Module1.vb
Code:
Imports SilkroadSecurityApi Imports System Imports System.Net Imports System.Net.Sockets Imports System.Threading Module Module1 Sub Main(ByVal args As String()) Dim recv_buffer As New TransferBuffer(4096, 0, 0) Dim ping_timer As New Stopwatch() Dim do_ping As Boolean = False Dim stats_timer As New Stopwatch() Dim last_stats_timer As New Stopwatch() Dim do_stats As Boolean = False Dim version As UInt32 = UInt32.Parse(args(1)) Dim locale As UInt32 = UInt32.Parse(args(0)) Dim hosts As New List(Of KeyValuePair(Of String, Int32)) Dim host_count As Int32 = Int32.Parse(args(2)) For x As Int32 = 0 To host_count - 1 hosts.Add(New KeyValuePair(Of String, Int32)(args(3 + x * 2), Int32.Parse(args(3 + x * 2 + 1)))) Next Dim connection_closed_times As New List(Of DateTime) Dim connect_errors As Int32 = 0 Dim receive_errors As Int32 = 0 Dim data_errors As Int32 = 0 Dim parse_errors As Int32 = 0 Dim send_errors As Int32 = 0 Dim misc_errors As Int32 = 0 Dim reconnect_time As Int32 = 5000 Dim stats_interval As Int32 = 1000 Dim stats_timeout As Int32 = 45000 Dim doExit As Boolean = False While doExit <> True Dim security As New SilkroadSecurityApi.Security ' This should actually be here rather than above in the C# example Using s As New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) Try ' Connect to the remote server Dim host As KeyValuePair(Of String, Int32) = hosts(connect_errors Mod hosts.Count) Console.WriteLine("Status: Now connecting to {0}:{1}", host.Key, host.Value) s.Connect(host.Key, host.Value) s.Blocking = False s.NoDelay = True Catch ex As Exception connect_errors = connect_errors + 1 Console.WriteLine("Error: Could not connect to the server." + Environment.NewLine + Environment.NewLine + ex.Message) If Console.KeyAvailable = True Then ' If the user wants to exit, let them. Dim key As ConsoleKeyInfo = Console.ReadKey(True) If key.Key = ConsoleKey.Escape Then doExit = True Exit While End If Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, connect_errors, reconnect_time) Thread.Sleep(reconnect_time) Continue While End If End Try last_stats_timer.Reset() last_stats_timer.Start() ' Need to keep track of stats time state ' Main logic loop While True Try If Console.KeyAvailable = True Then ' If the user wants to exit, let them. Dim key As ConsoleKeyInfo = Console.ReadKey(True) If key.Key = ConsoleKey.Escape Then doExit = True Exit While End If End If Catch ex As Exception misc_errors = misc_errors + 1 Console.WriteLine("Error: A misc error was encountered." + Environment.NewLine + Environment.NewLine + ex.Message) Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, misc_errors, reconnect_time) Thread.Sleep(reconnect_time) Exit While End Try ' Receive network data Try ' Receive logic, try to receive as much as possible, then pass to the security object Dim err As SocketError recv_buffer.Size = s.Receive(recv_buffer.Buffer, 0, recv_buffer.Buffer.Length, SocketFlags.None, err) If err <> SocketError.Success Then If err <> SocketError.WouldBlock Then Throw New Exception(String.Format("Receive returned error code {0}.", err)) End If Else If recv_buffer.Size > 0 Then Try security.Recv(recv_buffer) Catch ex As Exception Console.WriteLine("Error: Could not process the data from the server." + Environment.NewLine + Environment.NewLine + ex.Message) Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, data_errors, reconnect_time) Thread.Sleep(reconnect_time) Exit While End Try Else connection_closed_times.Add(DateTime.Now) Console.WriteLine("Error: The connection has been closed.") Console.WriteLine("This is disconnect # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, connection_closed_times.Count, reconnect_time) Thread.Sleep(reconnect_time) Exit While End If End If Catch ex As Exception receive_errors = receive_errors + 1 Console.WriteLine("Error: Could not receive data from the server." + Environment.NewLine + Environment.NewLine + ex.Message) Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, receive_errors, reconnect_time) Thread.Sleep(reconnect_time) Exit While End Try ' Process network data Try ' Obtain all queued packets and add them to our own queue to process later. Dim packets As List(Of Packet) = security.TransferIncoming() If packets Is Nothing Then Else For Each packet As Packet In packets ' Debugging Dim bytes As Byte() = packet.GetBytes() Console.WriteLine("[S->C][0x{0:X4}][{1} bytes][Enc: {2}][Msv: {3}]", packet.Opcode, bytes.Length, packet.Encrypted, packet.Massive) If packet.Opcode = &H5000 Then ' Handshake ' Ignore ElseIf packet.Opcode = &H2001 Then ' Identify Dim response As New Packet(&H6100, True, False) ' Version response.WriteUInt8(locale) response.WriteAscii("SR_Client") response.WriteUInt32(version) security.Send(response) do_ping = True ping_timer.Start() ElseIf packet.Opcode = &H2005 Then ' server specific information ' Ignore ElseIf packet.Opcode = &H6005 Then ' server specific information ' Ignore ElseIf packet.Opcode = &HA100 Then ' Version response Dim result As Byte = packet.ReadUInt8() If result = 1 Then If locale = 18 Then ' ISRO Dim response As New Packet(&H6107, True, False) ' Request ping servers security.Send(response) Else do_stats = True stats_timer.Start() Dim response As New Packet(&H6101, True) ' Request server list security.Send(response) End If Else result = packet.ReadUInt8() If result = 2 Then ' Updates available Dim ip As String = packet.ReadAscii() Dim port As UShort = packet.ReadUInt16() Dim new_version As UInt32 = packet.ReadUInt32() Dim new_file As Byte = packet.ReadUInt8() While new_file = 1 Dim file_id As UInt32 = packet.ReadUInt32() Dim file_name As String = packet.ReadAscii() Dim file_path As String = packet.ReadAscii() Dim file_size As UInt32 = packet.ReadUInt32() Dim file_pk2 As Byte = packet.ReadUInt8() new_file = packet.ReadUInt8() End While version = new_version Throw New Exception(String.Format("A new version is available.")) ElseIf result = 4 Then ' Server down Throw New Exception(String.Format("The GatewayServer is closed.")) ElseIf result = 5 Then ' Version too old version = version + 1 ' Try to correct it Throw New Exception(String.Format("The version is too old.")) ElseIf result = 1 Then ' Version too new version = version - 1 ' Try to correct it Throw New Exception(String.Format("The version is too new.")) Else ' Not much we can do here, user has to fix version their self. Throw New Exception(String.Format("Unhandled response {0}.", result)) End If End If ElseIf packet.Opcode = &HA107 Then ' Ping server response Dim count As Byte = packet.ReadUInt8() For x As Int32 = 0 To count - 1 Dim id As Byte = packet.ReadUInt8() Dim host As String = packet.ReadAscii() Dim port As UShort = packet.ReadUInt16() Next do_stats = True stats_timer.Start() Dim response As New Packet(&H6101, True) ' Request server list security.Send(response) ElseIf packet.Opcode = &HA101 Then ' Server list Dim new_entry As Byte = packet.ReadUInt8() While new_entry = 1 Dim id As Byte = packet.ReadUInt8() Dim name As String = packet.ReadAscii() new_entry = packet.ReadUInt8() End While new_entry = packet.ReadUInt8() While new_entry = 1 Dim id As UShort = 0 Dim ratio As Single = 0 Dim name As String = "" Dim country As Char = "?" Dim state As Byte = 0 Dim cur As UShort = 0 Dim max As UShort = 0 Dim extra1 As Byte = 0 Dim extra2 As Byte = 0 id = packet.ReadUInt16() If locale = 18 Then name = packet.ReadAscii() ElseIf locale = 12 Then name = packet.ReadAscii(950) ElseIf locale = 40 Then name = packet.ReadAscii(1251) ElseIf locale = 2 Then name = packet.ReadAscii(949) ElseIf locale = 4 Then name = packet.ReadAscii(936) ElseIf locale = 23 Then name = packet.ReadAscii(936) ElseIf locale = 38 Then name = packet.ReadAscii() Else Throw New Exception(String.Format("This program does not support the locale {0} yet.", locale)) ' name = packet.ReadAscii() ' Or comment out the line above and uncomment this one... End If If locale = 18 Then country = name(0) name = name.Remove(0, 1) ratio = packet.ReadSingle() Else cur = packet.ReadUInt16() max = packet.ReadUInt16() End If state = packet.ReadUInt8() ' Binds the server to the name server at the start of the packet. If locale = 4 Or locale = 23 Then extra1 = packet.ReadUInt8() If extra1 = 1 Then extra2 = packet.ReadUInt8() End If End If new_entry = packet.ReadUInt8() If locale = 18 Then Dim status As String If state = 1 Then status = "Open" Else status = "Check" End If Dim country2 As String If country = "0" Then country2 = "Korea" ElseIf country = "1" Then country2 = "USA" Else country2 = "<Unknown>" End If Console.WriteLine("[{0}] [{4}] {1} ({2}% full) [{3}]", id, name, ratio * 100.0F, status, country2) Else Dim status As String If state = 1 Then status = "Open" Else status = "Check" End If ' Default windows console with code page 1252 cannot display Unicode characters, ' so you will see ?'s. The string is correct though if you debug and check the name Console.WriteLine("[{0}] {1} {2} / {3} [{4}]", id, name, cur, max, status) End If End While last_stats_timer.Reset() last_stats_timer.Start() End If Next End If Catch ex As Exception Console.WriteLine("Error: Could not parse the data from the server." + Environment.NewLine + Environment.NewLine + ex.Message) Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, parse_errors, reconnect_time) Thread.Sleep(reconnect_time) Exit While End Try ' Send network data Try ' Check to see if we have any buffers to send Dim buffers As List(Of KeyValuePair(Of TransferBuffer, Packet)) = security.TransferOutgoing() If buffers Is Nothing Then Else For Each kvp As KeyValuePair(Of TransferBuffer, Packet) In buffers Dim buffer As TransferBuffer = kvp.Key Dim packet As Packet = kvp.Value Dim err As SocketError = SocketError.Success ' Debugging Dim bytes As Byte() = packet.GetBytes() Console.WriteLine("[C->S][0x{0:X4}][{1} bytes][Enc: {2}][Msv: {3}]", packet.Opcode, bytes.Length, packet.Encrypted, packet.Massive) ' Since TCP is a stream protocol, we have to support partial sends. To do this, we ' will just loop until we send all the data or an exception is generated. While buffer.Offset <> buffer.Size Dim sent As Int32 = s.Send(buffer.Buffer, buffer.Offset, buffer.Size - buffer.Offset, SocketFlags.None, err) If err <> SocketError.Success Then If err <> SocketError.WouldBlock Then Throw New Exception(String.Format("Send returned error code {0}.", err)) End If End If buffer.Offset += sent Thread.Sleep(1) End While ' If we should be pinging, we can reset the ping timer since data was sent. If do_ping = True Then ping_timer.Reset() ping_timer.Start() End If Next End If Catch ex As Exception send_errors = send_errors + 1 Console.WriteLine("Error: Could not send data from the server." + Environment.NewLine + Environment.NewLine + ex.Message) Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, send_errors, reconnect_time) Thread.Sleep(reconnect_time) Exit While End Try ' Main state logic checks Try ' Send the ping packet every 5s there is no other send. If do_ping = True Then If ping_timer.ElapsedMilliseconds >= 5000 Then ' We also set the time so we don't accidentally "multi-ping". That shouldn't ' happen in this program with a single thread, but it's an issue to look out for. ping_timer.Reset() ping_timer.Start() Dim response As New Packet(&H2002) ' Ping packet security.Send(response) End If End If ' Request stats each interval If do_stats = True Then If stats_timer.ElapsedMilliseconds >= stats_interval Then stats_timer.Reset() stats_timer.Start() Dim response As New Packet(&H6101, True) ' Request server list security.Send(response) End If End If If last_stats_timer.ElapsedMilliseconds > stats_timeout Then Throw New Exception(String.Format("No server list has been received in {0} ms.", last_stats_timer.ElapsedMilliseconds)) End If Catch ex As Exception misc_errors = misc_errors + 1 Console.WriteLine("Error: A misc error was encountered." + Environment.NewLine + Environment.NewLine + ex.Message) Console.WriteLine("This is error # {0}. Waiting {1} ms then trying again..." + Environment.NewLine, misc_errors, reconnect_time) Thread.Sleep(reconnect_time) Exit While End Try End While End Using End While Console.WriteLine("Status: The program is now exiting...") End Sub End Module
That's about it really, if you are familiar with VB.Net, then using the API shouldn't be too hard based on this example. The .Net class library system takes cares of most things for you. There might be easier/simpler/better ways to implement the code than I have shown, so keep that in mind. I'm not a VB.Net programmer, this is just an example for API usage!