VB.NET TCP Server Receiving Data Properly - vb.net

I have a multithread(with Backgroundworker) TCP Server which is developed by VB.NET. It works very good when client and server at same machine. But when i connect to server from another computer which is at same LAN it works different. At this case it works good until i start to send messages consecutively (3-4 messages at a second). I send :
Hi
Hi
Hi
Hi
Hi
and server gets this messages such :
Hi
HiHi
HiHiHi
Hi
etc.
It's very interesting that this issue occurs only when client is at other computer at LAN.
Here is my listen Sub :
Sub listen_port6(ByVal b As BackgroundWorker)
Dim server As TcpListener
server = Nothing
Try
Dim port As Int32 = 8085
server = New TcpListener(IP, port)
server.Start()
Dim bytes(1024) As Byte
Dim data As String = Nothing
While True
Dim client As Sockets.TcpClient = server.AcceptTcpClient()
Dim ipend As Net.IPEndPoint = client.Client.RemoteEndPoint
PublicIP = ""
If Not ipend Is Nothing Then
PublicIP = ipend.Address.ToString
End If
b.ReportProgress(1)
Dim stream As NetworkStream = client.GetStream()
Dim i As Int32
Dim k As Short
For k = 0 To 1024
bytes(k) = 0
Next
i = stream.Read(bytes, 0, bytes.Length)
While (i <> 0)
data = ""
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
Debug.Print(data)
i = stream.Read(bytes, 0, bytes.Length)
End While
client.Close()
End While
Catch errore As Exception
Error_Print(errore.Message)
Finally
server.Stop()
End Try
End Sub
Thanks in advance

Related

Can I send data using the same TCP port?

I have a TCP listener working but doesn't send anything. To get this TCP listener working I have a thread in a endless loop.
Now I need to answer to some specific packets and also be able to send data when the user request it using the same port that the TCP listener is using. The remote device keeps the connection open to be able to receive new data.
So, I must to create a new TCP client to send data to the current connected client or use the current listener socket?
Public Sub StopServer()
TcpOpen = False
Server.Stop()
ServerThread = Nothing
End Sub
Public Sub InitServer(ByVal Port As Integer)
Server = New TcpListener(IPAddress.Any, Port)
ServerThread = New Thread(AddressOf ConnectionListener)
ServerThread.IsBackground = True
ServerThread.Start()
TcpOpen = True
End Sub
Private Sub ConnectionListener()
Server.Start()
While True
If TcpOpen Then
If Server.Pending Then
Dim client As TcpClient = Server.AcceptTcpClient()
Dim T As New Thread(AddressOf StartTcpClient)
client.ReceiveBufferSize = 128000
T.IsBackground = True
T.Start(client)
Else
System.Threading.Thread.Sleep(10)
End If
Else
Exit While
End If
End While
End Sub
Private Sub StartTcpClient(ByVal client As TcpClient)
Dim bytesRead As Integer
Dim RxBuffer(1500) As Byte 'Original 1024
Dim RxDataStr As String = ""
Dim TxBuffer(1500) As Byte
Dim TxDataStr As String = ""
Dim TempData As String
Dim DataReceived As Boolean = False
Dim TimeX As Integer = 0
Dim RemoteIP As Net.IPEndPoint = client.Client.RemoteEndPoint
Dim RemoteIPStr As String = RemoteIP.Address.ToString
WriteRTBLog("Se inicio una nueva conexion TCP con la IP " & RemoteIPStr, Color.DarkViolet)
WriteRTBLog("Esperando datos...", Color.Black)
client.ReceiveTimeout = 30000
Try
While True
If client.GetStream.DataAvailable Then
bytesRead = client.GetStream.Read(RxBuffer, 0, RxBuffer.Length)
TimeX = 0 'Reset timer
If bytesRead > 0 Then
TempData = System.Text.ASCIIEncoding.UTF8.GetString(RxBuffer, 0, bytesRead) 'UTF8
RxDataStr += TempData
If Not DataReceived Then
DataReceived = True
WriteRTBLog("Se estan recibiendo datos...", Color.Purple)
End If
If RxDataStr.Contains("<") Then
'Process data
TxDataStr = AnswerProcessor(RxDataStr)
'New code- trying to send data
If TxDataStr.Length > 5 Then
TxBuffer = System.Text.Encoding.ASCII.GetBytes(TxDataStr)
client.Client.Send(TxBuffer)
End If
RxDataStr = "" 'Clean buffer
End If
End If
Else
If Not client.Connected Then
Exit While 'Close connection
Else
System.Threading.Thread.Sleep(10)
End If
End If
End While
If RxDataStr.Length > 0 Then
WriteRTBLog(String.Format("Se recibieron {0} bytes desde {1}", RxDataStr.Length.ToString, RemoteIPStr), Color.ForestGreen)
If Not client.Connected Then
WriteRTBLog("Conexion cerrada", Color.Black)
End If
End If
Catch ex As Exception
client.Close()
WriteRTBLog("Error en la conexion a " & RemoteIPStr, Color.Red)
WriteRTBLog(ex.Message, Color.Red)
WriteRTBLog(ex.StackTrace, Color.Red)
If RxDataStr.Length > 0 Then
' Create the file.
Dim PathX As String = Application.StartupPath & "\TCP_File_err" & CLng(DateTime.UtcNow.Subtract(New DateTime(1970, 1, 1)).TotalMilliseconds) & ".TCP"
Using fs As FileStream = File.Create(PathX)
Dim data As Byte() = New ASCIIEncoding().GetBytes(RxDataStr)
' Add some information to the file.
fs.Write(data, 0, data.Length)
End Using
WriteRTBLog(String.Format("Se recibieron {0} bytes desde {1} y se guardaron en {2}.", RxDataStr.Length.ToString, RemoteIPStr, PathX), Color.ForestGreen)
End If
End Try
End Sub
So, I must to create a new TCP client to send data to the current connected client or use the current listener socket?
No, neither. Use the socket you accepted that's connected to the client.

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)

Hostednetwork show login page

I'm currently writing a program that opens a wifi hotspot and enables Internet Connection sharing. I've got all of this working with netsh wlan set hostednetwork and some WinAPI calls.
Now I'd like to be able to show a login page when a client connects or block some websites/ports/etc.
My idea on this was to monitor the connection between me (the access point) and the client and whenever a packet on port 80 occurs, I send my login page or a "website blocked" page back instead of the real page. Currently the program is able to monitor the connection but I don't know how to send it back to the client.
This is my code (it's a bit long):
Dim myIpaddress As IPAddress
Dim theSocket As Socket
Dim receiveBuffer(4096) As Byte
Dim content As String = ""
Dim protocol As String = ""
Dim ipFrom As IPAddress
Dim ipTo As IPAddress
Dim portFrom As UInteger
Dim portTo As UInteger
Sub Listen()
theSocket = New Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP)
For Each int As NetworkInterface In NetworkInterface.GetAllNetworkInterfaces
If int.Description.Contains("Hosted") Then
For Each adress As UnicastIPAddressInformation In int.GetIPProperties.UnicastAddresses
If adress.Address.AddressFamily = AddressFamily.InterNetwork Then
myIpaddress = adress.Address
BindSocket()
End If
Next
End If
Next
End Sub
Sub BindSocket()
Try
theSocket.Bind(New IPEndPoint(myIpaddress, 0))
theSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, True)
theSocket.IOControl(IOControlCode.ReceiveAll, {1, 0, 0, 0}, {1, 0, 0, 0})
receiveBuffer = New Byte(theSocket.ReceiveBufferSize) {}
theSocket.BeginReceive(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceive), Nothing)
Catch ex As Exception
End Try
End Sub
Private Sub OnReceive(ByVal asyncresult As IAsyncResult)
'Get Length of packet (including header)
Dim readlength As UInteger = BitConverter.ToUInt16(Byteswap(receiveBuffer, 2), 0)
portTo = BitConverter.ToUInt16(Byteswap(receiveBuffer, 22), 0)
portFrom = BitConverter.ToUInt16(Byteswap(receiveBuffer, 24), 0)
'Get Protocol Type
If receiveBuffer(9) = 6 Then
protocol = "TCP"
ElseIf receiveBuffer(9) = 17 Then
protocol = "UDP"
Else
protocol = "???"
End If
'Get IP from and to
ipFrom = New IPAddress(BitConverter.ToUInt32(receiveBuffer, 12))
ipTo = New IPAddress(BitConverter.ToUInt32(receiveBuffer, 16))
content = ""
For i = 26 To readlength - 1
If Char.IsLetterOrDigit(Chr(receiveBuffer(i))) = True Then
content = content & Chr(receiveBuffer(i))
Else
content = content & "."
End If
Next
'TODO how to send my content to the client?
'Restart the Receiving
theSocket.BeginReceive(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceive), Nothing)
End Sub
Private Function Byteswap(ByVal bytez() As Byte, ByVal index As UInteger)
Dim result(1) As Byte
result(0) = bytez(index + 1)
result(1) = bytez(index)
Return result
End Function
Any ideas?

Get Requested URL

I have been trying to read any requested URLs to my localhost. I think the simplest way to do this is to use the TCPListener. Below is what I've built so far but I'm not sure how I can read the URL requested as a string. I actually want to take the first incoming URL, parse out the data I need then shut the TCPlistener down. Any idea how I can get the URL?
Dim TClient As New TcpListener(Net.IPAddress.Parse("127.0.0.1"), 80)
TClient.Start()
Dim gotIt As Boolean = False
Do While gotIt = False
Dim x = TClient.AcceptTcpClient()
Console.WriteLine(x)
TClient.Stop()
Loop
Using an example from the MSDN I was able to come up with this:
Dim server As TcpListener = Nothing
Dim port As Int32 = 80
Dim localAddr As IPAddress = IPAddress.Parse("127.0.0.1")
server = New TcpListener(localAddr, port)
server.Start()
Dim bytes(1024) As Byte
Dim data As String = Nothing
Dim client As TcpClient = server.AcceptTcpClient
data = Nothing
Dim stream As NetworkStream = client.GetStream
Dim i As Int32
i = stream.Read(bytes, 0, bytes.Length)
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i)
client.Close()
server.Stop()
The data variable contains the information I am looking for, just have to parse it out.
Thank you, #CoderDennis
What you're looking for is the Referer header.
String requestedUrl = request.getHeader("Referer");
Mind that Referer is case sensitive.
100% working!

VB .net : How can a Server handle multiple clients simultaneosly at an instance

I am facing a problem in VB .net Client/Server application where I am successfully able to talk between them using TCPListener and TCPClient class usage. However, when I try to connect another Client to the same server on the same welcome port, it errors out throwing an exception or behaves very unexpectedly.
Isn't it true that the Server connection is on a WELCOME PORT for all the clients, and that each client connected gets a new port to carry on its communication with the server AUTOMATICALLY (according to the Tomcat webserver working)?
OR, is the above statement untrue and that the APP program handle the connections manually?
Pls clarify with an example in VB .net, if possible?
The answer to your question is 'Yes it is true'. I do not have VB.NET code ready but you can have a look at C# code here C# sockets handling multiple clients.
Okay.. pasting my server code here for your comments... Pls pardon my ignorance in coding and teach me if I were wrong. Thanks.
The Client is more obvious... so dint paste it here.
Server:
Public Class ServerSide2
...other stuff...
Public Class Packet
Public packetType As String = "Data"
Public packetOwnerIPAddress As String
Public packetOwnerPort As String
Public content As String
Public Sub New(ByVal type As String, ByVal ip As String, ByVal port As String, ByVal data As String)
packetType = type
packetOwnerIPAddress = ip
packetOwnerPort = port
content = data
End Sub
End Class
Public Class Worker
Dim myLogger As Logger
Dim name As String
Dim ipClientAddress As IPAddress 'Client's IP address
Dim ipClientPort As Integer = 22222 'Client listening on this port
Dim tcpServer As TcpListener
Dim tcpClient As TcpClient
Dim networkStream As NetworkStream
Dim readSize As Integer = 100
Public Sub New(ByRef logger As Logger, ByVal id As String)
myLogger = logger
name = id
myLogger.Trace("A new Worker object has been created for client: {0}", ipClientAddress)
End Sub
'Listener code
Public Sub runClientHandler(ByVal ar As IAsyncResult)
'code to listen to independent client
Dim clientdata As String
Dim numBytesRead As Integer = 0
Thread.CurrentThread.Priority = ThreadPriority.Highest
' Get the listener that handles the client request.
Dim listener As TcpListener = CType(ar.AsyncState, TcpListener)
' End the operation and display the received data on
' the console.
tcpClient = listener.EndAcceptTcpClient(ar)
' Process the connection here. (Add the client to a
' server table, read data, etc.)
myLogger.Info("Client connected completed")
' Signal the calling thread to continue.
tcpClientConnected.Set()
networkStream = tcpClient.GetStream()
Dim ipEndPoint As IPEndPoint = tcpClient.Client.RemoteEndPoint
ipClientAddress = ipEndPoint.Address
myLogger.Info("A new Worker thread has been started.")
While Not stopping
myLogger.Trace("Start looping.")
Dim bytes(readSize) As Byte
numBytesRead = networkStream.Read(bytes, 0, bytes.Length)
clientdata = Encoding.ASCII.GetString(bytes, 0, numBytesRead)
'check for validity of the data
If numBytesRead = 0 Then
'connection lost
myLogger.Trace("No data read.")
Exit While
End If
If clientdata.Contains("SampleTest : {") Then
'Message box the client data
MsgBox("Test data from Client = " + clientdata)
myLogger.Trace("Test data from Client = " + clientdata)
ElseIf clientdata.Contains("Recieve Port : ") Then
'Heed to Client's request on the port number server should reply
Dim dest(5) As Char
Dim destString As String = ""
clientdata.CopyTo(15, dest, 0, clientdata.Length - 15)
ipClientPort = CInt(CStr(dest))
myLogger.Trace("Client Waiting on Port# : " + CStr(dest) + "for sorted packets.")
'MsgBox("Client Waiting on Port# : " + CStr(dest))
ElseIf clientdata.Contains("Packet Size : ") Then
Dim dest(5) As Char
Dim destString As String = ""
clientdata.CopyTo(14, dest, 0, clientdata.Length - 14)
readSize = CInt(CStr(dest))
myLogger.Trace("Client's communicated Packet Size : " + CStr(dest))
Else
myLogger.Info("Begin to queue Data Packets.")
While True
myLogger.Info("Data Packet.")
SyncLock Stats.locker
myLogger.Info("Got the lock.")
Stats.queueLength = Stats.requestQueue.Count
If Stats.queueLength < Stats.MAX_QUEUE_LENGTH Then
'Queue has some space to fit more packets
myLogger.Info("Queue has some space for this packet.")
Stats.packetNum = Stats.packetNum + 1
Dim newPacket As Packet = New Packet("Data", ipClientAddress.ToString, ipClientPort, clientdata)
Stats.requestQueue.Enqueue(newPacket)
Stats.sumQueueLength = Stats.sumQueueLength + Stats.requestQueue.Count
Stats.meanQueueLength = Stats.sumQueueLength / Stats.packetNum
myLogger.Info("Stats :: Packet #: {0}, QueueLength: {1}, MeanQueueLength: {2}.", Stats.packetNum, Stats.requestQueue.Count, Stats.meanQueueLength)
Else
'Queue is FULL, Ignore the packet
Stats.numDropPackets = Stats.numDropPackets + 1
myLogger.Info("Stats :: Dropped Packets: {0}.", Stats.numDropPackets)
End If
End SyncLock
numBytesRead = networkStream.Read(bytes, 0, bytes.Length)
clientdata = Encoding.ASCII.GetString(bytes, 0, numBytesRead)
'check for validity of the data
If numBytesRead = 0 Then
'connection lost
myLogger.Trace("No data read.")
Exit Sub
End If
End While
End If
End While
myLogger.Trace("End looping.")
End Sub
End Class
Sub ListeningThread()
Dim count As Integer = 0
tcpServer = New TcpListener(ipAddress, iPort)
tcpServer.Start()
Try
While Not stopping And count < Stats.MAX_CLIENTS
count = count + 1
Dim workerName = "worker:" + CStr(count)
Dim worker As Worker = New Worker(logger, workerName)
logger.Info("Waiting for a client to connect")
DoBeginAcceptTcpClient(worker, tcpServer)
logger.Info("Connected to {0}.", workerName)
'Add the client to the hashTable
'ADITYA later clients.Add(workerName, client)
If SortAndSendThrd Is Nothing Then
'Start a new thread
SortAndSendThrd = New Thread(SortAndSendThrdStart)
SortAndSendThrd.Priority = ThreadPriority.Highest
End If
If Not SortAndSendThrd.IsAlive Then
SortAndSendThrd.Start()
logger.Debug("Started off a Sort thread")
End If
'Dim i As Integer = 0
'Dim objValue As Object
'For Each objKey In clients.Keys
' objValue = clients.Item(objKey)
' 'MsgBox("[" & objKey.ToString & ", " & objValue.ToString & "]")
'Next objKey
End While
Catch ex As IOException
ToolStripStatusLabel1.Text = "ERROR : SocketException: {0}" + ex.Message
'MsgBox(ex.Message + ":::2")
Catch ex As SocketException
ToolStripStatusLabel1.Text = "ERROR : SocketException: {0}" + ex.Message
'MsgBox(ex.Message + ":::1")
End Try
'tcpServer.Stop()
'client.Close()
logger.Debug("The Server's listening handler has come to an end.")
End Sub
End Class
When I try to connect a second client to this, the server drops the connection 1 and behaves unpredictably.