-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
can anyone get a console app working using this library? I would love to see something like that, ever since i'm using SDL.NET for my client, a windows form app is pointless, and for the server i prefer a console app to save some cpu, and to not deal with invoking cross threads.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Hello jmcilhinney!
First of all, I want to thank you for creating these classes which are extremely helpful and easy to use.
I've been using your classes for quite some time now without problems but now I thought of trying to communicate from a website to a VB.Net application. The operation wasn't that successful though.
Does you class have support for websites? I don't think there's any difference from the TcpClass for websites and yours class. However, every time I try to connect from the website, it results with an "Connection refused" error.
Any ideas?
I'm currently using PHP, I've tried the official socket methods and a TcpClass which I found online.
Both of them returns "Connection refused" anyways...
Help appreciated!
//Zeelia
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
Zeelia
Hello jmcilhinney!
First of all, I want to thank you for creating these classes which are extremely helpful and easy to use.
I've been using your classes for quite some time now without problems but now I thought of trying to communicate from a website to a VB.Net application. The operation wasn't that successful though.
Does you class have support for websites? I don't think there's any difference from the TcpClass for websites and yours class. However, every time I try to connect from the website, it results with an "Connection refused" error.
Any ideas?
I'm currently using PHP, I've tried the official
socket methods and a
TcpClass which I found online.
Both of them returns "Connection refused" anyways...
Help appreciated!
//Zeelia
It sounds like there's an issue with the way you're trying to connect, not with the classes you're trying to use to connect.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Hi! Thanks for the quick reply.
I don't know where the problem lies since I'm trying to connect just as I am in VB.Net.
The VB.Net application is able to connect but the PHP one can't...
Here's how I'm trying to connect in PHP:
Code:
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, $host, $port);
These lines would equivalent to the lines I'm using in VB.Net:
Code:
Client = New MessageClient(txtIP.Text, CInt(txtPort.Text))
Client.Connect()
Any ideas?
It seems like the PHP version requires the server socket to accept the connection since there is a method in PHP called socket_accept() which the servers use.
I haven't read through your entire code but I think that your code accepts automatically, right?
*EDIT* I might also be trying to connect to the wrong IP address. Currently I'm trying to connect to 127.0.0.1 but now I remembered that the file lies on a webhost. So I tried to connect to my external IP but it says that it can't find the host
*EDIT** The error was caused by the webhost which only has some specific ports open (which I didn't know)
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Hi,
I am trying to do client application, which would be connected to multiple servers. Can you help me how to run each connection in a different thread? And how to pass different address to the new instance (Private WithEvents client As New MessageClient(hostName, remotePort))?
So that application will be like your demo client, but I would like to start a new instance in the new thread, not in the new form.
Appreciated the example in the code.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
zzyzx
Hi,
I am trying to do client application, which would be connected to multiple servers. Can you help me how to run each connection in a different thread? And how to pass different address to the new instance (Private WithEvents client As New MessageClient(hostName, remotePort))?
So that application will be like your demo client, but I would like to start a new instance in the new thread, not in the new form.
Appreciated the example in the code.
The whole point of my code is that you simply create the objects, tell them to connect and then tell them to communicate. Any multi-threading is handled internally, so if you want multiple clients then you simply create multiple clients. If you want to pass them different addresses then that's what you do. If you know how to pass one address to one MessageClient object then you know how to pass multiple addresses to multiple objects: it's simply doing the one thing multiple times.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
jmcilhinney
The whole point of my code is that you simply create the objects, tell them to connect and then tell them to communicate. Any multi-threading is handled internally, so if you want multiple clients then you simply create multiple clients. If you want to pass them different addresses then that's what you do. If you know how to pass one address to one MessageClient object then you know how to pass multiple addresses to multiple objects: it's simply doing the one thing multiple times.
Probably I need to learn a lot about object programming :rolleyes:. I try to create a service that will communicate with various hardware modules and write data in database. I'm electronic hobbyst, not the proffessional programmers, so maybe you can help me with following code .
Code:
Imports Wunnell.Net
Public Class Form1
Private ReadOnly host As String = "localhost"
Private ReadOnly port As Integer = 8081
Private WithEvents client As New MessageClient(host, port)
Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
Me.client.Dispose()
End Sub
Private Sub connectButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles connectButton.Click
'Me.connectButton.Enabled = False
'Connect to the server.
'Me.client.Connect()
End Sub
Private Sub sendButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles sendButton.Click
Dim message = Me.messageTextBox.Text
Me.client.Send(message)
Me.UpdateLog(String.Format("Message (=>{0}:{1}): {2}", Me.host, Me.port, message))
Me.messageTextBox.SelectAll()
Me.messageTextBox.Select()
End Sub
Private Sub PromptToReconnect(ByVal message As String, ByVal caption As String, ByVal icon As MessageBoxIcon)
Me.sendButton.Enabled = False
Me.connectButton.Enabled = True
Select Case MessageBox.Show(message, _
caption, _
MessageBoxButtons.YesNoCancel, _
icon)
Case Windows.Forms.DialogResult.Yes
'Try again to connect.
Me.connectButton.PerformClick()
Case Windows.Forms.DialogResult.No
'Do nothing.
Case Windows.Forms.DialogResult.Cancel
Me.Close()
End Select
End Sub
Private Sub UpdateLog(ByVal text As String)
Me.logTextBox.AppendText(text & ControlChars.NewLine)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
client.Connect()
AddHandler client.ConnectionAccepted, AddressOf Accepted
AddHandler client.MessageReceived, AddressOf MessageRecieved
AddHandler client.ConnectionFailed, AddressOf failed
AddHandler client.ConnectionClosed, AddressOf cclosed
End Sub
Private Sub MessageRecieved(ByVal Sender As Object, ByVal e As MessageReceivedEventArgs)
Me.UpdateLog(String.Format("Message ({0}=>): {1}", e.Host, e.Message))
End Sub
Private Sub failed(ByVal Sender As Object, ByVal e As MessageReceivedEventArgs)
Me.PromptToReconnect("The specified server could not be found. Would you like to try again?", _
"Connection Failed", _
MessageBoxIcon.Error)
End Sub
Private Sub cclosed(ByVal Sender As Object, ByVal e As MessageReceivedEventArgs)
Me.PromptToReconnect("The connection was closed by the server. Would you like to reconnect?", _
"Connection Closed", _
MessageBoxIcon.Warning)
End Sub
Private Sub Accepted(ByVal Sender As Object, ByVal e As ConnectionEventArgs)
Dim host = e.Host.ToString()
Me.Text = String.Format("{0}=>{1}", Me.client.LocalPort, host)
Me.UpdateLog("Info: Connection accepted to " & host)
Me.sendButton.Enabled = True
End Sub
End Class
As you can see I put all code on an form and this is the end of my programming knowledge :o . Now I need a little help on how to dynamically create objects (clients) which would be connected to different servers.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Hi jmcilhinney,
Im trying to implement a client server. The server is a Windows Service and the client is a Winforms application. However, the service and client keeps crashing on the following code:
Protected Overridable Sub OnConnectionAccepted(ByVal e As ConnectionEventArgs)
Me._synchronisingContext.Post(AddressOf RaiseConnectionAccepted, e)
End Sub
I have read bits and pieces on the synchronizationcontext but don't completely understand it. How would you recommend i fix the code to work. Will i need the old version before you used the synchronisatiocontext or is there a configuration i need to set for it to run under a windows service..?
Help would greatly be appreciated!
Thanks
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
A crash is an unhandled exception. An exception has an error message, provided as an aid to diagnosing and fixing the problem.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Considering this code works on a GUI and not as a service i thought it would be a problem with using the synchronizationcontext which is why i didn't provide the exception. Sorry about that.
The code i posted is throwing this error when wrapped in a try catch block:
Sytem.NullReferenceException {"Object reference not set to an instance of an object."}
It was captured in MessageClientServerBase.vb
Is there any other part of the exception you need..?
The only thing i can think of is that because there is no UI thread in a windows service, this is causing the problem but yeah im unsure of how to resolve it.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
Johno2518
Considering this code works on a GUI and not as a service i thought it would be a problem with using the synchronizationcontext which is why i didn't provide the exception. Sorry about that.
The code i posted is throwing this error when wrapped in a try catch block:
Sytem.NullReferenceException {"Object reference not set to an instance of an object."}
It was captured in MessageClientServerBase.vb
Is there any other part of the exception you need..?
The only thing i can think of is that because there is no UI thread in a windows service, this is causing the problem but yeah im unsure of how to resolve it.
If it's working in a WinForms app and not in a service then it is likely that the issue is related to that fact, but it's certainly not definite. Also, the fact that it's a service specifically means that you CAN'T use the ISynchronizeInvoke interface, because there are no controls to call Invoke on.
The thing is, the reason you need to use either the ISynchronizeInvoke interface or the SynchronizationContext class in a WinForms app is that you can only access your UI controls on the UI thread. In a Windows service there is no UI, so there's no reason to have to marshal your method call(s) to a specific thread. Basically, you don't need either. You can do whatever you want on whatever thread you happen to be on at the time. You just have to make sure that different threads don't interfere with each other's data.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
So what do i change the synchronizationcontext to..? Instead should i just be raising the relevant event..?
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
Johno2518
So what do i change the synchronizationcontext to..? Instead should i just be raising the relevant event..?
You shouldn't be changing it to anything. You should be getting rid of it because, as I said, you don't need it. Wherever the Send or Post methods of the SynchronizationContext were used, you just call the delegated method directly, e.g. where you had this:
vb.net Code:
mySynchronizationContext.Send(AddressOf SomeMethod)
you would replace it with this:
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Ok, i'll give it a go.
Thanks for the information.
Just one more quick question. In the GUI, it raises events in the server. Will this work in a windows service. So if i change it to as you described of calling the method directly, will it still raise events..?
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Thanks for the help. It still raises events, so thats good. I have changed the code to this:
Code:
''' <summary>
''' Raises the <see cref="ConnectionAccepted" /> event.
''' </summary>
''' <param name="e">
''' Contains the data for the event.
''' </param>
''' <remarks>
''' The event will be raised on the thread on which the current instance was created.
''' </remarks>
Protected Overridable Sub OnConnectionAccepted(ByVal e As ConnectionEventArgs)
Try
Me._synchronisingContext.Post(AddressOf RaiseConnectionAccepted, e)
Catch Ex As Exception
RaiseConnectionAccepted(e)
End Try
End Sub
''' <summary>
''' Raises the <see cref="ConnectionClosed" /> event.
''' </summary>
''' <param name="e">
''' Contains the data for the event.
''' </param>
''' <remarks>
''' The event will be raised on the thread on which the current instance was created.
''' </remarks>
Protected Overridable Sub OnConnectionClosed(ByVal e As ConnectionEventArgs)
Try
Me._synchronisingContext.Post(AddressOf RaiseConnectionClosed, e)
Catch Ex As Exception
RaiseConnectionClosed(e)
End Try
End Sub
''' <summary>
''' Raises the <see cref="MessageReceived" /> event.
''' </summary>
''' <param name="e">
''' Contains the data for the event.
''' </param>
''' <remarks>
''' The event will be raised on the thread on which the current instance was created.
''' </remarks>
Protected Overridable Sub OnMessageReceived(ByVal e As MessageReceivedEventArgs)
Try
Me._synchronisingContext.Post(AddressOf RaiseMessageReceived, e)
Catch Ex As Exception
RaiseMessageReceived(e)
End Try
End Sub
The reason is this code needs to be portable for clients and servers that may run in a service or winforms application. I know its not that ellegant, but it tries to use the standard code (for winforms) and if it fails because its running as a service it uses the other code to raise the event.
If there is a better way of detecting what kind of thread is being run, please let me know. At the moment this works and is all i need for the time being but would appreciate some detection code sample (if any exists).
Thanks again!
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
Johno2518
The reason is this code needs to be portable for clients and servers that may run in a service or winforms application. I know its not that ellegant, but it tries to use the standard code (for winforms) and if it fails because its running as a service it uses the other code to raise the event.
If there is a better way of detecting what kind of thread is being run, please let me know. At the moment this works and is all i need for the time being but would appreciate some detection code sample (if any exists).
Thanks again!
I do wish that people would provide the whole story up-front. If you're trying to write code that can handle two different situations then that's going to be different to code that handles just the first situation and different again to code that handles just the second situation. If you want a solution then we need to know what problem we're solving. If you only provide half the relevant information then you're unlikely to get a working solution. Keep that in mind when posting in future.
Anyway, you said originally that you got a NullReferenceException. That is presumably because Me._synchronisingContext is Nothing, which is presumably the case because SynchronizingContext.Current returns Nothing when not in either a WinForms or WPF application. As is always the case, you shouldn't try to do something and then clean up when it fails if it would be simple to check whether the action is valid beforehand. In this case, that check is indeed very simple:
vb.net Code:
If Me._synchronisingContext Is Nothing Then
'No synchronisation required.
RaiseConnectionAccepted(e)
Else
'Marshal a call to the main thread.
Me._synchronisingContext.Post(AddressOf RaiseConnectionAccepted, e)
End If
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Originally i only wanted it to work for a service, but i then thought more about the typical usage of the DLL which could comprise of both.
I changed my mind on how i was going to use the library. Your last reply makes sense.
My solution was just a quick one to see if it resolved the situation for the time being.
Thanks for the help. Greatly appreciated :)
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
I was sent to this thread by a user on the MS Forumns site. The project makes absolutely no sense to me what so ever. I've migrated over from VB6 and have been nearly tearing my hair out trying to build a simple Client/Server app but it just won't work! Then I saw this solution from the guy who suggested it and it made me even more angry because I don't understand it at all. OK I'm very new to vb.net and refuse to go "back to school" as I've hear the phrase used before. When I read the sample code it didnt have anything in there about how to accept the connection from the client or how to put the received message/text into a simple text box, absolutely nothing! I'm sorry but I HATE people that produce what they call easy to use solutions that are as complicated as hell to use!
Erm hello, a tutorial might be nice instead of a project that yeah works but doesnt show how to do any of the things I want to do, simply or simplicity is what im looking for NOT complicated. I'm sorry but I don't understand properties, methods etc... that well in Vb.net. Why can't someone just come up with a simple solution to the problem that doesn't include 101 references here and there and everywhere!
Client: One text box, one button ("Send"), one button ("Connect") :-
Click Connect, Write in the text box "Hello world", Click Send = Job Done!
Simple code to do this please!
Server: One text box
Sub Routine to accept connection, process message/text received :-
Message Received and processed : Put into the text box = Job Done!
Simple code to do this please!
Someone for pittys sake work with me on this, I have a major problem and stress out very very easily and become angry very quickly (its called a brain defect - not enough of a chemical allowing me to retain control of myself - rather like ADHD), my apologies for any offence but can't help it.
Dave.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
First off, the solution posted here is simple...very simple. In fact, given the task, and the language, I'm not sure how you could write the code to do it any more simply. This is NOT complicated, providing you have some experience in VB.NET.
However, there may be a couple of reasons why you think it is complicated.
Reasons such as...
Quote:
Originally Posted by darkdemon28
OK I'm very new to VB.net
And
Quote:
Originally Posted by darkdemon28
I'm sorry but I don't understand properties, methods etc... that well in Vb.net.
At this point in your VB.NET career I would venture to say that, given those two things, nearly everything will be complicated for you. It will continue to be complicated for you until you have the one thing you don't have now, and that is experience.
Second, I don't care about your medical conditions and I don't care about your emotional state. What I do care about is your attitude and that needs to be addressed if you wish to continue be a member in good standing on this web site.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
jmcilhinney
There was no problem per se. The way I was doing it originally, i.e. with a SynchronisingObject property, is the same as some classes in the Framework do it. One advantage of this is that it gives you the choice of leaving the SynchronisingObject property empty and having events raised on a thread pool thread or setting it and having events raised on a specific thread. I didn't really see a reason why you specifically want my classes to raise their events on thread pool threads though, so the change I made did three things for me:
1. It meant that a caller could completely ignore the fact that there was multi-threading involved and, in fact, wouldn't even know it from the interface. All interaction with an instance of one of my classes would occur on the same thread without any indication that any other threads were involved. There was no need for the caller to go to the (admittedly tiny) effort of setting the SynchronisingObject property to get synchronous events.
2. It made my code a bit cleaner.
3. It gave me a chance to play with the SynchronizationContext class, which I haven't had the pleasure of previously.
Like I said, there was nothing actually wrong with the old implementation. If you're interested in doing something similar but aren't 100% sure how then I'm happy to provide the old code. That said, you might also be interested in using the SynchronizationContext class as the new code does.
can you provide me with the old source plz? i would like to see the difference.
thankyou before.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
Shinra
can you provide me with the old source plz? i would like to see the difference.
thankyou before.
I don't actually have the old code anymore, but I can certainly recreate it without too much trouble. When I get a chance today, I'll re-implement one of the classes that currently uses a SynchronizationContext and give it a SynchronisingObject property.
-
1 Attachment(s)
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
Shinra
can you provide me with the old source plz? i would like to see the difference.
thankyou before.
It took a little longer to get around to it than I planned but I've redone the project so that the MessageClient and MessageServer classes now use a SynchronisingObject property. Do a "Find in Files" on that and you'll find all the changes.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
I keep getting "Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host." aswell .. me on line "Dim byteCount = stream.EndRead(ar)" of MessageServer.Read - it's in a try catch and still throws the error :(
Anyone solved this?
Thanks
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Um... how am i supposed to uniquely identify a user ...
Just say I have a LAN of 100 people accessing a remote server across the net - to the server they all will have the same IP address and the MessageReceived etc events just pass around the HostInfo structure that only contains the IP and port but nothing to uniquely identify each connection.
Thanks
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
all good ... by the port... whops
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
um... also i am using:
Data = System.Text.Encoding.ASCII.GetString(System.Text.Encoding.Unicode.GetBytes(e.message))
to convert the MessageReceived Response to ascii... but if the data is split across one send on the client (sent in vb script with windsock) the Data has some rubbish chrs at the end and the first received message and the 2nd received message has some rubbish chrs at the begining of data.
Is it possible to talk more natively in ascii rather than having to convert from unicode?
Thanks
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
i00
um... also i am using:
Data = System.Text.Encoding.ASCII.GetString(System.Text.Encoding.Unicode.GetBytes(e.message))
to convert the MessageReceived Response to ascii... but if the data is split across one send on the client (sent in vb script with windsock) the Data has some rubbish chrs at the end and the first received message and the 2nd received message has some rubbish chrs at the begining of data.
Is it possible to talk more natively in ascii rather than having to convert from unicode?
Thanks
Kris
If you want to pass the data as ASCII then just call ASCII.GetBytes when sending and ASCII.GetString when receiving. Once you convert a String to binary though, you MUST convert that binary back to a String using the same encoding. Think about it. Binary data is just numbers. It's how you interpret those numbers that gives them meaning. If you have a set of numbers that represents some Unicode text, how can you convert it to text using ASCII and expect to get a sensible result?
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
By the way, I didn't in my code but you can use a StreamWriter to write to the NetworkStream at one end and a StreamReader to read the NetworkStream at the other. You simply provide the Stream and the Encoding when you create them and then use them in the same way as you would to read or write a file.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
jmcilhinney
If you want to pass the data as ASCII then just call ASCII.GetBytes when sending and ASCII.GetString when receiving. Once you convert a String to binary though, you MUST convert that binary back to a String using the same encoding. Think about it. Binary data is just numbers. It's how you interpret those numbers that gives them meaning. If you have a set of numbers that represents some Unicode text, how can you convert it to text using ASCII and expect to get a sensible result?
I am using ascii.getstring when receiving ... and it is putting the junk there
and the data was sent in ascii with the clients ... the clients use winsock in a vb script btw...
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
If the client sent the data as ASCII then you can read it as ASCII. If there's junk in the data then it was put there by the client. They must be adding some sort of header and/or footer to the data. If you can send ASCII data using a TcpClient and read it correctly using your server then you know it's not the server that's the issue. You need to determine what that header/footer is so that you can parse it and remove it from the data.
-
1 Attachment(s)
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Great - 99% working now ... but this error makes it unusable (see attached screenshot)
Thanks
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Just had another error on the same line this one reads: "Unable to read data from the transport connection: EndReceive can only be called once for each asynchronous operation.."
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
This is the stack trace for "Unable to read data from the transport connection: EndReceive can only be called once for each asynchronous operation.." that occurs on the line "Dim byteCount = stream.EndRead(ar)"
Code:
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at Wunnell.Net.MessageServer.Read(IAsyncResult ar) in C:\SARAH Registration Server\SARAH Registration Server\Wunnell.Net.MessageClientServer\MessageServer.vb:line 452
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
Any ideas?
Thanks
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
The call stack for the "forcibly closed" error is:
Code:
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at Wunnell.Net.MessageServer.Read(IAsyncResult ar) in C:\SARAH Registration Server\SARAH Registration Server\Wunnell.Net.MessageClientServer\MessageServer.vb:line 452
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
I just thought that I mention that I'm not ignoring these posts. I just don't know the solution because I have never encountered these errors and I don;t have the time for extensive testing right now. You might do better to post in the VB.NET forum about this specific problem and link back to this thread. Someone may have solved a similar issue who would not ever see your question in this thread.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Also get another error occasionally - does not take me to a line though ...
Error is: "Exception has been thrown by the target of an invocation."
This is the call stack:
Code:
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)\r\n
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)\r\n
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)\r\n
at System.Delegate.DynamicInvokeImpl(Object[] args)\r\n
at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme)\r\n
at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj)\r\n
at System.Threading.ExecutionContext.runTryCode(Object userData)\r\n
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)\r\n
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n
at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme)\r\n
at System.Windows.Forms.Control.InvokeMarshaledCallbacks()\r\n
at System.Windows.Forms.Control.WndProc(Message& m)\r\n
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)\r\n
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)\r\n
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)\r\n
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)\r\n
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)\r\n
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)\r\n
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)\r\n
at System.Windows.Forms.Application.Run(ApplicationContext context)\r\n
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()\r\n
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()\r\n
at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)\r\n
at SARAH_Registration_Server.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81\r\n
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)\r\n
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)\r\n
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()\r\n
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)\r\n
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n
at System.Threading.ThreadHelper.ThreadStart()
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
i00
Also get another error occasionally - does not take me to a line though ...
Error is: "Exception has been thrown by the target of an invocation."
That error message occurs on the original thread when an exception occurs on a secondary thread. It's a safe bet that the original exception is being thrown in one of the callbacks. Is there an inner exception? There should be and that should contain the original exception.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Also thank you from Denmark :thumb:.
This piece of code is simple, well-commented and very easy to expand upon.
I'm using a rewritten version of the code (allowing encryption, signatures and more complex data-transmission) with great success as an integrated part of a larger solution. There are occasional minor problems, that probably ties to the rewrites, but I'll mention one here anyways, since the solution may be helpful:
* Loss of net on either side caused an unhandled exception, that had to be handled in an application-event (NetworkAvailabilityChanged).
Regards and thanks again
Tom
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
I am using this to talk between a vb6 winsock control
and all seems to be working well except for one thing...
I can receive data with no problems from the .net server, but when i send it i get no errors... the vb6 app just never receives the data - never had a problem before with the vb6 server that i used to use.
Any ideas?
Thanks
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
i00
I am using this to talk between a vb6 winsock control
and all seems to be working well except for one thing...
I can receive data with no problems from the .net server, but when i send it i get no errors... the vb6 app just never receives the data - never had a problem before with the vb6 server that i used to use.
Any ideas?
Thanks
Kris
None I'm afraid.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Great stuff all working well as an app ... just when i make it a service i get the following error:
Code:
System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="Wunnell.Net.MessageClientServer"
StackTrace:
at Wunnell.Net.MessageClientServerBase.OnConnectionAccepted(ConnectionEventArgs e)
at Wunnell.Net.MessageServer.AcceptTcpClient(IAsyncResult ar)
at System.Net.LazyAsyncResult.Complete(IntPtr userToken)
at System.Net.ContextAwareResult.CompleteCallback(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.ContextAwareResult.Complete(IntPtr userToken)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
InnerException:
(No inner exception)
I made a test app that does the following (only one user connects to the test app so didnt bother having a message buffer for each user):
The test app throws the same error...
The test app consists of:
vb Code:
Public Class Service1
Private WithEvents server As Wunnell.Net.MessageServer
Protected Overrides Sub OnStart(ByVal args() As String)
server = New Wunnell.Net.MessageServer(8016)
End Sub
Protected Overrides Sub OnStop()
server.Dispose()
End Sub
Dim message As String
Private Sub server_MessageReceived(ByVal sender As Object, ByVal e As Wunnell.Net.MessageReceivedEventArgs) Handles server.MessageReceived
message &= e.Message
Dim arrMessage = Split(message, vbCrLf)
For i = LBound(arrMessage) To UBound(arrMessage)
If i = UBound(arrMessage) Then
'we are the last one
message = arrMessage(i)
Else
If LCase(arrMessage(i)) = "action:ping" Then
server.Send(e.Host, "Action:pong" & vbCrLf)
End If
End If
Next
End Sub
End Class
any ideas?
Thanks
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
The exception is telling you that there's a NullReferenceException in MessageClientServerBase.OnConnectionAccepted. What line is it thrown on and what reference on that line is Nothing?
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
hrm ..ok ... the following was causing the issue:
vb Code:
Private _synchronisingContext As SynchronizationContext = SynchronizationContext.Current
Worked fine after changing to:
vb Code:
Private _synchronisingContext As New SynchronizationContext
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
jmcilhinney
The exception is telling you that there's a NullReferenceException in MessageClientServerBase.OnConnectionAccepted. What line is it thrown on and what reference on that line is Nothing?
Fixed as mentioned above ... and it was this throwing it:
vb Code:
Protected Overridable Sub OnConnectionAccepted(ByVal e As ConnectionEventArgs)
Me._synchronisingContext.Post(AddressOf RaiseConnectionAccepted, e)
End Sub
_synchronisingContext was nothing
Regards
Kris
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
That's because the SynchronizationContext class only works in WinForms and WPF applications. It's purpose is to marshal a method call to the UI thread. There's no UI in a Windows service so there's no UI. There's no need to marshal method calls to a specific thread to updated controls so the SynchronizationContext class is not relevant.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Lovely work! :) Congratulations. I have to admit you saved me some billions years to make a lib like this hehehe.
I have one doubt. I observed you used Dim buffer As Byte() = Me.Encoding.GetBytes(message), in Send methods, to send data. I can remove this, and send data in ascii instead? is safe to do this? why do you use encoding? (just a curiosity)
Again, thanks for this great job!
Bernardo Salazar
Venezuela
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Ready, im figured out how to transmit and receive in ASCII. Just replaced Me.Encoding.GetString with Me.Encoding.ASCII.GetString in server and client classes, rebuilded de DLL, and voila!
Sorry for disturbing you in programmer's olympus! hehehehe :p
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
berniesf
Ready, im figured out how to transmit and receive in ASCII. Just replaced Me.Encoding.GetString with Me.Encoding.ASCII.GetString in server and client classes, rebuilded de DLL, and voila!
Sorry for disturbing you in programmer's olympus! hehehehe :p
That may get the job done but it's not the right way to do it. If you want to convert text to binary or vice versa then you need to use an Encoding object. ASCII is just an Encoding object that encodes in ASCII. If you wanted to use ASCII then you should have done one of two things:
1. Assigned System.Text.Encoding.ASCII to the Encoding property and used the code as is.
2. Got rid of the Encoding property and just used System.Text.Encoding.ASCII.GetBytes and .GetString instead.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Efectively, im replaced the line Me.Encoding.ASCII.GetString (that line give me a warning) with System.Text.Encoding.ASCII.GetString and all is working as suposed to do. Many thanks, and congratulations for your cool project. :wave:
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Hi, im back again with a little question :bigyello:
Im added a dictionary (string, date) to project, everytime clients transmit data (key are host: port, value are hour), updates the dictionary with the last hour of transmition. A timer see every 30 seconds the dictionary, if any value are greater than 60 minutes, it remove from combobox and dictionary, but... how i can remove from hosts list and how close the port used? i see in MessageServer class a private sub called RemoveClient. Its possible to invoke that sub to close the port inside my app? or another mechanism to close a port and remove from hosts list?(i am making this 'cos sometimes clients disconnects and server keep port open, in this way i close the unused ports). Thanks again!
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
berniesf
Hi, im back again with a little question :bigyello:
Im added a dictionary (string, date) to project, everytime clients transmit data (key are host: port, value are hour), updates the dictionary with the last hour of transmition. A timer see every 30 seconds the dictionary, if any value are greater than 60 minutes, it remove from combobox and dictionary, but... how i can remove from hosts list and how close the port used? i see in MessageServer class a private sub called RemoveClient. Its possible to invoke that sub to close the port inside my app? or another mechanism to close a port and remove from hosts list?(i am making this 'cos sometimes clients disconnects and server keep port open, in this way i close the unused ports). Thanks again!
You are only using one port at the server end. If you want to close a client connection then call Close on the TcpClient.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Sorry for disturbing you... how can call TcpClient close from inside server app? i have some minutes trying but nothing, my level of expertise are very low. :(
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
berniesf
Sorry for disturbing you... how can call TcpClient close from inside server app? i have some minutes trying but nothing, my level of expertise are very low. :(
When you accept a connection from a client a TcpClient is created. If you want to close that connection then you call Close on that TcpClient.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Hi again!
After tons of coffee cups, boxes of cigarrettes, and an attemp to commit suicide :p i have this:
Public Sub TerminateClient(Host As String)
For Each client As KeyValuePair(Of TcpClient, HostInfo) In Me.clients
If client.Value.ToString = Host Then
Me.RemoveClient(client.Key)
Exit For
End If
Next
End Sub
I added to MessageServer class. Its right?
Greetings from Venezuela
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Does that RemoveClient method call Close on the TcpClient?
Also, from that code alone, it looks like the HostInfo should be the keys and the TcpClient should be the value. Are you using a TcpClient to get a HostInfo from that Dictionary anywhere else? If not then you should switch them.
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Hi JMCILHINNEY!
Let me comment mi Sub. I call RemoveClient, 'cos i observed you call that routine when error occurs on Read sub on MessageServer class. I think this remove client.
Im using the dictionary that is declared at the very beginning of the MessageServer class, is declared in this way:
Private ReadOnly clients As New Dictionary(Of TcpClient, HostInfo)
MessageServer add a element to this dictonary on AcceptTCPClient
'Remember the client and its host information.
Me.clients.Add(client, host)
After studying your code (mainly MessageServer class), i made the routine that i posted before, but i dont know if im in the right path.
Greetings!
Bernardo Salazar
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Dear Mr. jmcilhinney,
Your Message Client-Server is an amazing program that works fine. But, it has some problem with the following issues. Can you tell me how can I fix that?
Problem
When the client computer gets shutdown due to a power lose or something it raises an error.
"IO Exception was unhandled"
Error Message:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
The same happens on the client side too.
Can you fix the problem please?
Thanks in advance.
fashion games, utorrent
-
Re: [VB2008/.NET 3.5] Asynchronous TcpListener & TcpClient
Quote:
Originally Posted by
creativedas
Dear Mr. jmcilhinney,
Your Message Client-Server is an amazing program that works fine. But, it has some problem with the following issues. Can you tell me how can I fix that?
Problem
When the client computer gets shutdown due to a power lose or something it raises an error.
"IO Exception was unhandled"
Error Message:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
The same happens on the client side too.
Can you fix the problem please?
Thanks in advance.
You can see that there are various exception handlers in the code to handle various situations like that. This sounds like one more like that that you can add for yourself.