Strange socket problems - vb.net

I have a server I wrote using Asynchronous sockets. In the piece that accepts new connections I am getting a problem where some users are saying that some of the times they get this error on the server when the client tries to re-connect to the server:
"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"
After this error occurs the server goes dead and no new clients can connect until I physically quit the server program and start it again. So what should I do when I get this error? I tried to essentially restart the server in my code by closing the socket (listener.Close()) and then calling the same code I used to create and bind to the socket in the beginning, but then I get an error saying that I can't bind to the same port again.
So, two questions. First off, what is the proper way to handle that error and prevent it from essentially killing my server? Next, what is the proper way to restart a server through my code? Just calling .close() on the listener and then starting it again doesn't work in this case.
Thanks
Here is the code that accepts the connection request
Private Sub connectionRequest(ByVal ar As IAsyncResult)
Try
Dim thisListener As Socket = CType(ar.AsyncState, Socket)
Dim handler As Socket = thisListener.EndAccept(ar)
Dim remoteEndPoint As IPEndPoint
remoteEndPoint = handler.RemoteEndPoint
thisListener.Listen(10)
thisListener.BeginAccept(New AsyncCallback(AddressOf connectionRequest), thisListener)
thisListener.NoDelay = True
thisListener.Ttl = 32
Dim state As New StateObject
state.workSocket = handler
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf dataArrival), state)
handler.NoDelay = True
Catch ex As Exception
End Try
End Sub

Could you show us the code that you have for accepting connections?
You shouldn't have to restart your server. You should just fix the bug in your accept code in your server.
Clients can and will experience this problem when a server isn't accepting connections quickly enough, and/or if the listen backlog queue is too short for the rate at which new connections are being established and at which the server is accepting them.

Related

TCP/IP Messaging Application VB.net - IP Address / Port-Forwarding Questions

I am developing a piece of scientific software in VB.net that I intend to distribute. Part of the application will involve communication with a server (and other clients). For all intents and purposes the communication will be like a chat application.
I have developed the software using sockets, and it works fine when testing at home on my local network. Below is basically how I send messages:
Dim serverIPString as String = "192.168.1.5"
Dim serverPort as long = 65500
dim messageString as String = "Hello"
Dim Client As New System.Net.Sockets.TcpClient(serverIPString, serverPort)
Dim Writer As System.IO.StreamWriter(Client.GetStream())
Writer.Write(messageString)
Writer.Flush()
Writer.Close()
And this is how I listen:
Public Class TCPIPListener
Dim initalised As Boolean = False
Dim port As Long
Dim IP As System.Net.IPAddress
Dim ourListener As TcpListener
Dim ourClient As TcpClient
Dim ourMessage As String
'''''''''''
'' ctors ''
'''''''''''
Public Sub New()
initalised = False
End Sub
'Takes IP and port and starts listeing
Public Sub New(inIP As String, inPort As Long, inExchange As messageExchange)
'Try to set the IP
Try
IP = System.Net.IPAddress.Parse(inIP)
Catch ex As Exception
Exit Sub
End Try
'Set the port
port = inPort
initalised = startListener()
End Sub
'''''''''''''''
'' Listening ''
'''''''''''''''
Private Sub Listening()
ourListener.Start()
End Sub
'starts listener
Public Function startListener() As Boolean
ourListener = New TcpListener(IP, port)
ourClient = New TcpClient()
Dim ListenerThread As New Thread(New ThreadStart(AddressOf Listening))
ListenerThread.Start()
initalised = True
Return True
End Function
'Called from a timer on the form
Public Function tick() As Boolean
If Not initalised Then
Return False
End If
If ourListener.Pending = True Then
ourMessage = ""
ourClient = ourListener.AcceptTcpClient()
Dim Reader As New System.IO.StreamReader(ourClient.GetStream())
While Reader.Peek > -1
ourMessage = ourMessage + Convert.ToChar(Reader.Read()).ToString
End While
messagebox(ourMessage)
End If
Return True
End Function
End Class
Using this approach, every client will be listening for messages sent from the server, and any messages sent will go to the server and be directed to the relevant client - it's a little inefficient but necessary for the way my software works.
The problem is that I am having real trouble getting this to work across the internet. If I send a message to a local IP address it works fine, even from the debugger. If I use a external IP address I get the following:
No connection could be made because the target machine actively refused it XXX.XXX.XXX.XXX:65500"
I have turned on port forwarding with my router and set up the correct port (65500 here) to forward to my PC running the lister (192.168.1.5) for both TCP and UDP. This website it tells me this port is open, and those either side are not.
If I right click on the exe and run as administrator, my antivirus pops up and says it is doing something suspicious when I start the listener (which I guess if anything is encouraging). If I then add my application to the list of exceptions and run it again, then check to see if the port is listening (using this) I find my application listening on the correct port (if I stop the application it is gone). However the client application still gives the same error above. If I use a random IP address rather than the one of the listener I get a different 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 XXX.XXX.XXX.XXX:65500"}
I suspect I am not taking the correct approach to this. I am fine with most aspects of VB, but have not really tackled this sort of problem before. When it comes to distributing software I really don't want my customers to have to mess around with deep settings to get this application to work. Any help will be immensely useful to me!
Another problem I guess I will face in the future is if multiple clients have the same external IP but different internal IPs (I intend to distribute to universities). Under these circumstances I guess port forwarding will not work.
Thanks very much in advance (and apologies for the long post)!
If you set your server to listen for connections on 192.168.1.5 then it will only allow connections from that specific IP address. The address you give a TcpListener is the IP address which you will accept connections from.
Since the 192.168.1.5 address is internal no one outside your network will be able to connect to your server. Make your server listen to 0.0.0.0 (or the equivalent IPAddress.Any) instead to make it allow connections from anyone.

TelnetExpect Reading Output from Stream in VB.NET

Good Morning,
I have been tasked with writing a program that locates the local port a MAC Address is registered to, and to do that I need to SSH and Telnet into Cisco devices and receive the output of the commands so I can parse it and decide what to do with the information.
So far I have the SSH connection and parsing done no problem thanks to Renci.SshNET. But I am having trouble with the Telnet, I set it up to use Telnetlib.dll and I know it works because I can do "show users" on the switch I'm connecting to and see that one of the vty lines are being occupied by my application. But in the application I'm writing all I get is the application freezing up, none of the buttons work, and I can't see the mouse when I hover over the window, so I'm guessing that the application isn't liking something at run-time.
The code I'm using, in VB.NET is:
Using client As TcpClient = New TcpClient(host, 23)
Dim tel As TelnetStream = New TelnetStream(client.GetStream)
Dim buff(client.ReceiveBufferSize) As Byte
Dim result As String
tel.SetRemoteMode(TelnetOption.Echo, False)
Dim exp As Expector = New Expector(tel)
exp.Expect("username: ")
exp.SendLine(username)
exp.Expect("password: ")
exp.SendLine(password)
exp.Expect(">")
tel.Read(buff, 0, buff.Length)
result = System.Text.Encoding.ASCII.GetString(buff)
MessageBox.Show(result)
End Using
Telnetlib.dll include the definitions for the Expector, SendLine, Expect, and TelnetStream.
I did some debugging and found that it freezes when it goes to execute the result = System.Text.Encoding.ASCII.GetString(buff)
command.
Thanks for any help.

Vb.Net Detect if application server is down

I have developed a .Net application that I want to share to users through shared file in the LAN that is managed through a Domain server. When the server is up and running its fine but when the server is shut down an error comes. I have access to sql server database in that server. When server is shut down it gives a fatal error and application stops. How to detect the error of server being down?
I am connecting to the server through the following code:
Dim sql As String
Dim daCourseMaster As SqlDataAdapter
Try
sqlConn = New SqlConnection(connString)
sqlConn.Open()
sql = " ... "
daCourseMaster = New SqlDataAdapter(sql, sqlConn)
daCourseMaster.Fill(dsDataset, "table")
dvRegister = New DataView
dvRegister = dsDataset.Tables("courseRegisters").DefaultView
dgvCourseRegister.DataSource = dvRegister
Catch ex As Exception
MsgBox(Err.Description)
End Try
Now there might be different reasons why user can not login to the server: either the server name is wrong or user name or password is wrong or thebserver might be shut down! How to differentiate between these reasons to let the user know what might be the reason to failed login?
Use this code before the code that do the sharing (if the code in a Sub):
If Not My.Computer.Network.Ping(" You Server Name or Server IP") Then Exit Sub
or (if the code in a Function):
If Not My.Computer.Network.Ping(" You Server Name or Server IP") Then Exit Function
Lets say, you need to query your database. When you open connection and then when you execute your query, use Try-Catch Block and intercept SqlException. It has different codes, so you can test it for connectivity -related codes
Try
Using conn as new SqlConnection(...)
conn.Open()
....
End Using
Catch (connEx as SqlException)
' sql - related error handling
Catch (ex as Exception)
' here handle all other exception
End Try
this way, you can let user know that connection has lost and "try again later" or something like this

Open a port with vb? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Can anyone please share a simple code for VB 2008 to open a port. I would like it to be just like utorrent how you can change the listening port for data transfer. thanks a lot if you can help me!
As Avner indicated, uTorrent is not simple code. If you'd like to do anything on that level, then you've got a lot to do.
Here is a simple sample socket program you can build on.
Imports System.Net
Imports System.Net.Sockets
Module Module1
Sub Main()
Console.WriteLine("Enter the host name or IP Address to connect to:")
Dim hostName = Console.ReadLine().Trim()
If hostName.Length = 0 Then
' use the local computer if there is no host provided
hostName = Dns.GetHostName()
End If
Dim ipAddress As IPAddress = Nothing
' parse and select the first IPv4 address
For Each address In Dns.GetHostEntry(hostName).AddressList
If (address.AddressFamily = AddressFamily.InterNetwork) Then
ipAddress = address
Exit For
End If
Next
' you will have to check beyond this point to ensure
' there is a valid address before connecting
Dim client = New TcpClient()
Try
' attempt to connect on the address
client.Connect(ipAddress, 80)
' do whatever you want with the connection
Catch ex As SocketException
' error accessing the socket
Catch ex As ArgumentNullException
' address is null
' hopefully this will never happen
Catch ex As ArgumentOutOfRangeException
' port must be from 0 to 64k (&HFFFF)
' check and ensure you've used the right port
Catch ex As ObjectDisposedException
' the tcpClient has been disposed
' hopefully this will never happen
Catch ex As Exception
' any other exception I haven't dreamt of
Finally
' close the connection
' the TcpClient.Close() method does not actually close the
' underlying connection. You have to close it yourself.
' http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B821625
client.GetStream().Close()
' then close the client's connection
client.Close()
End Try
End Sub
End Module
Be aware that socket programming is quite complicated and you will have to thoroughly test your code for all edge cases.
Good luck!
uTorrent is anything but a "simple code". It's a complicated application with a lot of network logic going on beyond just opening a port and pushing bits in and out of it.
But your starting point for low-level communications handling would be the System.Net.Sockets namespace, which contains the Socket class. It allows low-level control such as opening a port, listening for connections and handling them yourself.
Here's a tutorial about Socket programming in VB.NET, but you'll probably find more information if you search for "C# Socket tutorial". C# syntax is a bit different than VB.NET, but it uses the same classes and the same concepts, so you'll probably be able to apply the lessons to your own code.

Unable to execute SQL command in windows service

I'm working on creating a windows service that will send emails to a customer when they are within a month of having their submission expire. I'm using vb.net in Visual Studios 2008
Because it's a windows service it's very difficult to debug. Trying to narrow down my error I created a "sendDebugEmail" method that sends me an email if it gets to a certain line. The emails never make it past "dr = cmd.ExecuteReader()"
I'm wondering what I am doing wrong. My SQL statement should work fine. I've tested it in my SQL server database.
I've created a dummy_database that I just made in sql server as well. I added an INSERT sql statement for the dummy table i have in there just to see if i could actually access a database. All the table takes in is the line number and time it was sent. When I run my windows service that database updates just fine.
Any help would be appreciated. Thanks
Dim conn As New SqlConnection(connString2)
sendDebugEmail("134")
SQL = "Select email FROM _Customer WHERE custID in (SELECT custID FROM _OnlineCustomer WHERE ExpirationDate <= '6-20-12' AND ExpirationDate >= '6-10-12')"
Dim cmd As New SqlCommand(SQL, conn)
sSubject = "hello"
sBody = "This is test data"
Dim dr As SqlDataReader
sendDebugEmail("143")
Try
dr = cmd.ExecuteReader() // This is were it stops
sendDebugEmail("147")
While dr.Read
sendDebugEmail("152")
Try
LogInfo("Service woke up")
Dim i As Integer = 0
' Prepare e-mail fields
sFrom = "test#gmail.com"
sTo = "test1#gmail.com"
sCc = "test2#gmail.com"
Dim oMailMsg As MailMessage = New MailMessage
oMailMsg.From = sFrom
oMailMsg.To = sTo
oMailMsg.Cc = sCc
' Call a stored procedure to process the current item
' The success message
oMailMsg.Subject = sSubject + "(Success)"
oMailMsg.Body = sBody + "Email has been sent successfully."
' Send the message
If Not (oMailMsg.To = String.Empty) Then
SmtpMail.Send(oMailMsg)
End If
Catch obug As Exception
LogEvent(obug.Message)
Finally
End Try
End While
Catch ex As Exception
Finally
dr.Close()
cmd.Dispose()
conn.Close()
conn.Dispose()
End Try
End Sub
/////////////////////////////////////////////////////////////////////////////////
Problem Solved: I set up my connection but I never opened it.
I needed conn.open()
The thing that helped me most was adding this code into my last catch statement:
sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)
It send me an email of the stackTrace and made it very easy to debug
Are you trapping and swallowing exceptions? If you are, stop. Let exceptions service crash the service: the exception will be logged in the Event log. The only exceptions you should trap are those you can actually recover from (though its valid to catch the exception, log it and rethrow it via throw;).
Have you instrumented your code with log4net (http://logging.apache.org/log4net/), or something similar? You should be, especially for a daemon like a Windows service — how else are you (or operations) going to diagnose problems with the service when the occur (as they will).
Edited to note:
You should be using using statements: all those ADO.Net objects are IDisposable. It makes for cleaner code.
Consider using a SqlDataAdapter to fill a DataTable or DataSet with your results set. The pattern you're using:
read a row from SQL
while read was successful
send an email
read a row from SQL
will ultimately lead to blocking in your database. Talking to a mail server has the potential for a high latency. If the mail server doesn't answer, or you have network congestion, or any of a number of other reasons, you're going to be left hanging until the mail is sent or an exception is thrown due to timeout. And your SQL Query is going to be sitting there with read locks on the table and indices from which you're reading data, blocking people attempting to do updates, inserts or deletes. Your production DBAs will be...vexed. You want to keep your locks moving and get the locks released as quick as you can.
If you are sure about your code (with no exceptions) i think you should check the authentication you are using to connect the SQL server(inside the connection string within the app.config file/inline code of the windows service).
If you are using SQL authentication for this (check the connection string for user name sa and its password) setting the account type of the windows service to LocalService will help you.
If the SQL connection is using windows authentication then setting the account type of the windows service to LocalSystem will help you.
The Account type modification can be done after installation also. For this go to Control panel->Administrative tools->Services->YourService right click and select Propertes->Logon and perform it there. If you are selecting the LocalSystem (windows authentication) you will be asked to enter the login credentials of the account in which the service is running.
In the case of windows authentication in SQL connection the credentials of the account in which the service is running will be taken for SQL connectivity also.
Hope this helps ...
One more suggestion put a sleep statement on your process when it starts so oyu have time to attach to it
Problem Solved: I set up my connection but I never opened it.
I needed conn.open()
The thing that helped me most was adding this code into my last catch statement:
sendDebugEmail(ex.Message & vbcrlf & ex.stackTrace)
It send me an email of the stackTrace and made it very easy to debug