Reconnect to server after losing connection with Tcp Socket - vb.net

I tried to use dont linger to reconnect to the server when losing connection
Public Class Agent
Dim bytes(1024) As Byte
Dim remoteEP As New IPEndPoint(IPAddress.Parse(My.Settings("HostIP").ToString), CType(My.Settings("HostPort"), Integer))
Dim permis As New SocketPermission(NetworkAccess.Connect, TransportType.Tcp, "", SocketPermission.AllPorts)
Dim S As New Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
If connect is successful it goeos to getdatadb, if not it goes to socketclose first and then it tries to connect again
Sub Connect()
Try
S.Connect(remoteEP)
Catch ex As Exception
socketclose()
S.Connect(remoteEP)
End Try
GetDataDb()
End Sub
with this to close the socket
Sub socketclose()
Dim myOpts As New LingerOption(True, 1)
S.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, myOpts)
S.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, False)
S.Shutdown(SocketShutdown.Both)
S.Close()
End Sub
but it still shows exception
Once the socket has been disconnected, you can only reconnect again
asynchronously, and only to a different EndPoint. BeginConnect must
be called on a thread that won't exit until the operation has been
completed.
I don't know why dontlinger doesn't work.

Related

Vb.net application connect to multiple server via TCP/IP

I made a Winforms application to work with 4 different machines by connecting with them via TCP/IP. Somehow, the connection sometimes seems disconnected and reconnecting after a short while. May I know is it I used too much TCP client and caused them congested??
Below is the function/method to connect those machine...with 4 of them different function names to connect each of the machine, but the code is more or less the same:
Public Async Sub connect_Machine_Ethernet(ByVal mainForm As Form1)
If Machine_COMPort.IsOpen Then
Machine_COMPort.Close()
End If
If (IsNothing(Machine_client)) Then
'do nothing, since obj is not created
Else
Try
Machine_client.GetStream.Close()
Machine_client.Close()
Catch exp As Exception
End Try
End If
Try
Machine_client = New TcpClient
Machine_client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, True)
Dim result = Machine_client.BeginConnect(Machine_ModuleIP_txt.Text, CInt(Machine_ModulePort_txt.Text), Nothing, Nothing)
result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(1))
Machine_client.GetStream.BeginRead(Machine_ethernet_buffer, 0, Machine_ethernet_buffer.Length, AddressOf Machine_TCP_read, Machine_ethernet_buffer)
DisplayMsg("Machine Ethernet connection established")
manual_connection_LED.StateIndex = 3
Machine_client_isConnected = True
Machine_TCP_Reconnect_btn.Invoke(Sub() Machine_TCP_Reconnect_btn.Visible = False)
Catch ex As Exception
DisplayMsg("Error : Unable to connect to the Machine Ethernet connection")
manual_connection_LED.StateIndex = 0
Machine_client_isConnected = False
If (IsNothing(Machine_client)) Then
'do nothing, since obj is not created
Else
Try
Machine_client.GetStream.Close()
Machine_client.Close()
Catch exp As Exception
End Try
End If
End Try
End Sub
'Read Machine TCP message
Sub Machine_TCP_read(ByVal ar As IAsyncResult)
Try
Dim buffer() As Byte = ar.AsyncState
Dim bytesRead As Integer = Machine_client.GetStream.EndRead(ar)
Dim Message As String = System.Text.Encoding.ASCII.GetString(Machine_ethernet_buffer, 0, bytesRead)
If Message = "" Then
'----check connection
If Machine_client.Connected Then
Machine_client.Close()
connect_Machine_Ethernet(Me)
End If
Else
DisplayMsg("Input Received from machine : " & Message)
Process_machine_Feedback(Message) 'perform any data logic from the message
Machine_client.GetStream.BeginRead(Machine_ethernet_buffer, 0, Machine_ethernet_buffer.Length, AddressOf Machine_TCP_read, Machine_ethernet_buffer)
End If
Catch ex As Exception
DisplaySystemMsg(ex.Message)
DisplayMsg("Marking machine Ethernet disconnected from the server")
manual_connection_LED.StateIndex = 0
Machine_client_isConnected = False
Exit Sub
End Try
End Sub
'Send message to TCP
Public Sub Machine_TCP_send(ByVal str As String)
Try
sWriter = New StreamWriter(Machine_client.GetStream)
sWriter.WriteLine(Chr(2) & str & Chr(3)) 'add prefix suffix
sWriter.Flush()
DisplayMsg("Message send to the machine via TCP: " & str)
Catch ex As Exception
DisplayMsg("Error : Message failed to send to themachine!")
End Try
End Sub

TCP Client program won't connect to my server

I'm trying to create a basic chat server-client program using TCP/IP and port forwarding in VB.NET. The code is derived almost entirely from Carlo De Silva's YouTube tutorials. I'm consistently having an issue connecting the two clients. When I open the client on my computer and another client on the other computer, I get the error "A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond [ip]:5757"
There are three different programs: the server, the client, and the client on the other end (the friend client.) The server and the client both use my local IP, which is accessed programmatically, so it couldn't be due to a typo. The friend client uses my external IP, which I've checked as of today (2018-09-09) and it is correct. I've set up port-forwarding on my router using TCP&UDP with my local IP, which was different when I checked it today, but I've updated the rule and the problem persists. Everything is done over port 5757. The firewall isn't an issue - I tried turning it off on the other computer and the friend client still fails to connect.
I've checked the port-forwarding tester on the website yougetsignal.com, which says that port 5757 is closed on both my local and external IP. But at the time of writing, I've currently got open the server and two client programs (both of which use my local IP,) and I am able to successfully send messages between those two client programs. So if they are able to send messages between the server and back, I don't understand why the website says that the port is closed on my local IP.
Can anyone help me work out why the friend client is failing to connect?
Server code:
Module MainModule
Dim _server As TcpListener
Dim _listOfClients As New List(Of TcpClient)
Dim hostName As String = System.Net.Dns.GetHostName
Dim ip As String = System.Net.Dns.GetHostEntry(hostName).AddressList(0).ToString
Dim extip As String = "86.25.175.94"
Dim port As Integer = 5757
Sub Main()
Console.Title = "SERVER"
Try
_server = New TcpListener(IPAddress.Parse(ip), port)
_server.Start()
Threading.ThreadPool.QueueUserWorkItem(AddressOf NewClient)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.ReadLine()
End Sub
Private Sub NewClient(state As Object)
Dim client As TcpClient = _server.AcceptTcpClient
Try
Threading.ThreadPool.QueueUserWorkItem(AddressOf NewClient)
_listOfClients.Add(client)
Dim ns As NetworkStream = client.GetStream
While True
'Creates a buffer
Dim toReceive(100000) As Byte
Dim length As Integer = ns.Read(toReceive, 0, toReceive.Length)
Dim text As String = Encoding.ASCII.GetString(toReceive, 0, length)
For Each c As TcpClient In _listOfClients
If c IsNot client Then 'Sends a message to every other client besides this one.
Dim nns As NetworkStream = c.GetStream 'New Network Stream
nns.Write(Encoding.ASCII.GetBytes(text), 0, text.Length)
End If
Next
Console.WriteLine(text)
Console.WriteLine()
'Sends a received message receipt.
Dim toSend() As Byte = Encoding.ASCII.GetBytes("Message Received...")
ns.Write(toSend, 0, toSend.Length)
End While
Catch ex As Exception
If _listOfClients.Contains(client) Then
_listOfClients.Remove(client)
End If
Console.WriteLine(ex.Message)
End Try
End Sub
End Module
Client code:
Module MainModule
Dim _client As TcpClient
Dim hostName As String = System.Net.Dns.GetHostName
Dim ip As String = System.Net.Dns.GetHostEntry(hostName).AddressList(0).ToString
Dim extip As String = "86.25.175.94"
Dim port As Integer = 5757
Sub Main()
Console.Title = "Chat Client (Host)"
Try
'Gets the local ip address
_client = New TcpClient(ip, port)
'This thread listens for receiving messages from the server.
Threading.ThreadPool.QueueUserWorkItem(AddressOf ReceiveMessages)
While True
'Starts a new stream
Dim ns As NetworkStream = _client.GetStream()
Dim message As String = Console.ReadLine()
Dim toSend() As Byte = Encoding.ASCII.GetBytes(message)
'Sends the message to the server
ns.Write(toSend, 0, toSend.Length)
End While
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
Console.ReadLine()
End Sub
Private Sub ReceiveMessages(state As Object)
Try
While True
'Starts a new network stream (receiving stream) to listen for any receiving messages.
Dim rs As NetworkStream = _client.GetStream
'Creates a buffer to receive text
Dim toReceive(100000) As Byte
'Reads anything coming in from the server.
Dim length As Integer = rs.Read(toReceive, 0, toReceive.Length)
'Converts the byte to text
Dim text As String = Encoding.ASCII.GetString(toReceive, 0, length)
Console.ForegroundColor = ConsoleColor.Green
Console.WriteLine(text)
Console.ResetColor()
Console.WriteLine()
End While
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Sub
End Module
The client and friend client are only different by one line of code:
_client = New TcpClient(extip, port) 'Friend client connects to external IP
_client = New TcpClient(ip, port) 'My client connects to local IP
Your issue is here:
_server = New TcpListener(IPAddress.Parse(ip), port)
The TcpListener(IPAddress, Int32) overload specifies which IP address to accept connections from, meaning it will accept connections from ONLY that IP (in this case your local address).
To fix this you've got to listen for connections at IPAddress.Any (equivalent to 0.0.0.0), which specifies that it should accept connections from any IP address.
_server = New TcpListener(IPAddress.Any, port)

My program can't read an ASCII string from TCP connection, keeps looping

I'm connecting to a specific TCP port of a server, do stuff, and I need to disconnect at some point, then wait for the server to open its port again and reconnect.
My program loops forever.
To disconnect from the server, I sent from the server the string "TCP:OFF" and the close the port (server side). Whenever my program reads this line, I want it to close its connection and wait the server to open its port again. This is because of the TCP/IP protocol.
The problem is that the specific ASCII string sent from my server is not read until I put my mouse over my window (weird). At the end, I want my program to work by itself and minimized, without human intervention.
There must be a problem in the timing of my networkStream reading.
Code
While tcpClient.Connected() = False
Try
tcpClient.ReceiveTimeout = 1000
tcpClient.SendTimeout = 1000
tcpClient.Connect("192.168.10.100", 10003)
Console.WriteLine("Connection OK")
System.Threading.Thread.Sleep(1000)
Catch ex As Exception
Console.WriteLine("ERRORR : Server unreachable")
System.Threading.Thread.Sleep(1000)
End Try
End While
Dim networkStream As NetworkStream = tcpClient.GetStream()
If networkStream.CanRead And networkStream.DataAvailable Then
Try
ReadData = ""
Dim myReadBuffer As Byte() = New Byte(7) {}
Dim numberOfBytesRead = networkStream.Read(myReadBuffer, 0, myReadBuffer.Length)
ReadData = Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead)
Console.Write(ReadData & vbCrLf)
Catch ex As Exception
Console.Write("Error reading data")
End Try
End If
If ReadData = "TCP:OFF" Then
tcpClient.Close()
ReadData = ""
Console.WriteLine("Closing connection")
System.Threading.Thread.Sleep(5000)
tcpClient = New TcpClient
End If
I'm doing a Windows form program in latest Visual Studio.

What I must change to make this code listen on UDP port?

I'm trying to create a server Windows Form application but my code throw a 0x80004005 error when call the Listen method.
What I'm doing wrong?
Private Sub StartUdpReceiveThread(ByVal Puerto As Integer)
If Not UdpOpen Then
Try
permission = New SocketPermission(NetworkAccess.Accept, TransportType.Udp, "", SocketPermission.AllPorts)
sListener = Nothing
permission.Demand()
'Dim ipHost As IPHostEntry = Dns.GetHostEntry("")
Dim ipAddr As IPAddress = IPAddress.Any
ipEndPoint = New IPEndPoint(ipAddr, CInt(Me.PuertoEscuchaLbl.Text))
'sListener = New Socket(ipAddr.AddressFamily, SocketType.Unknown, ProtocolType.Udp)
sListener = New Socket(ipAddr.AddressFamily, SocketType.Dgram, ProtocolType.UDP)
' Associates a Socket with a local endpoint
sListener.Bind(ipEndPoint)
sListener.Listen(5)
' Begins an asynchronous operation to accept an attempt
Dim aCallback As New AsyncCallback(AddressOf AcceptCallback)
sListener.BeginAccept(aCallback, sListener)
PrintLog("Server listening on " & ipEndPoint.Address.ToString & " port: " & ipEndPoint.Port)
UdpOpen = True
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End If
End Sub
Edit:
CallBack method
Public Sub AcceptCallback(ar As IAsyncResult)
Dim listener As Socket = Nothing
' A new Socket to handle remote host communication
Dim handler As Socket = Nothing
Try
' Receiving byte array
Dim buffer As Byte() = New Byte(1023) {}
' Get Listening Socket object
listener = DirectCast(ar.AsyncState, Socket)'<-- Here raises an error
' Create a new socket
handler = listener.EndAccept(ar)
handler.NoDelay = False
' Creates one object array for passing data
Dim obj As Object() = New Object(1) {}
obj(0) = buffer
obj(1) = handler
handler.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, New AsyncCallback(AddressOf ReceiveCallback), obj)
' Begins an asynchronous operation to accept an attempt
Dim aCallback As New AsyncCallback(AddressOf AcceptCallback)
listener.BeginAccept(aCallback, listener)
Catch ex As Exception
MessageBox.Show(ex.ToString())
End Try
End Sub
Don't just pick the first IP address in IPHostEntry.AddressList but search the array for an IPv4 address. See the example on this MSDN page.

Check if port 57875 is closed on localhost VB.Net?

I am trying to see if port 57875 on localhost, the computer, is closed.
Here is the code I have so far:
Try
Dim checkPort As TcpClient = New TcpClient("localhost", 57875)
Catch ex As Exception
MsgBox("WARNING: Port 57875 is not forwarded ! The game will probably encounter an error !")
End Try
Even if it is forwarded, it will think it isn't. What is wrong with the code?
Here you have an example:
Dim host As String = "localhost"
Dim port As Integer = 57875
Dim addr As IPAddress = DirectCast(Dns.GetHostAddresses(host)(0), IPAddress)
Try
Dim tcpList As New TcpListener(addr, port)
tcpList.Start()
Catch sx As SocketException
'Catch exception - No available port
End Try