I think I solved the problem. I don't want to update the entire article for this modifications because it takes too long.
I noticed that Andre was going to send you some code to solve your issue. Could you tell me what the solution was in the end?
Is their an updated version of this code, I see you provided a custom update here, and just wondering if the download here contains all the latest updates? Looking forward to trying this out, its exactly what Im looking for
I know that a lot of time has passed, but would it be possible to receive the modified version that fixes the problem with multiple messages being packed in one receive and messing up
First of all, thank you for contributing such an excellent and valuable resource to CodeProject...it is one of the best and most thorough contributions I've seen, and it will be a great resource for my project.
I don't think I am understanding something about the operation of the delimiters. In your examples (running under Visual C# Express), whenever I send the delimiter characters, I get the following exception: "Arithmetic operation resulted in an overflow".
I tested it in the console echo program...I changed the delimiter to ABCDE. Then I tried it with the frmEchoServer demo, and it triggered when I type "ALAZ" in the telnet session.
Delimiter is used to determining message boundaries. After the host finds the delimiter array on receiving message, it knows that a full message has arrived and parse it.
In your case, after typing ALAZ in telnet session, the host found the delimiter on receiving message and process it. But, because before the delimiter there's no information, it generates an exception. If you type "MessageALAZ" the message will exists ("Message") because there's message information after delimiter is found.
Thanks for the quick reply. I had thought this also, but it actually doesn't seem to hold true. I can type whatever I want before ALAZ and it always gives me the same exception.
The really curious part is that I have the same behavior in Visual Studio 2005, unless I set the delimiter type to be dtMessageTailIncludeOnReceive...with that set it works fine, and exactly as I would expect it to. But not in Visual C# Express 2008.
Also...in a question related to your last question...I've turned Nagle off, so I would expect to not require any sort of flush, but occasionally not all of my sends make it to the client. Am I missing something? Is there a flush of some kind to force sending any buffered bytes?
But no, it's just a pretty cool coincidence...he's done a lot more network programming than I have. I've done some off and on for the past 10 years or so, but I'm definitely not a guru.
Definitely, that would be great. In an effort to foil the spambots...the domain is "nagleresearch", it's a dot com, and my user name is jnagle.
Thank you very much for your library, I am using it for a new distance learning project involving thousands of clients. In testing (the Framework 2.0 version) we found that chat sessions left open overnight are often 'broken' in the morning.
As a developer using Microsoft RTC SDK (SIP) I found it necessary to use keep-alive messages to avoid the remote endpoints (or intermediate routers) silently dropping part of the socket connection. The keep-alives are sequentially numbered to detect lost messages and to provide a quantitative measurement of backlog to both ends of a socket connection. The recipient of the keep-alive replies to the sender with the original sequence number, and the number of the previous sequence number it had received.
In previous attempts to use .NET Sockets, I am aware that the developer can select features that guarantee the end-to-end integrity of the socket connection, but that going that route is not necessarily an advantage. Keep-Alives sent at the application level are a good compromise.
You can configure the IdleTimeout on the server. If client stops to send messages and the time expires IdleTimeout, the connection is closed.
I don't know if passing a value of 0 in IdleTimeout can disable it. If not, pass a large number (Timeout.Infinite).
I need more information about Keep-Alive and endpoints/routers behavior. Do you have some article? If yes, could you please send me! (in email)
Thanks, but the desired function is to maintain the link connected, not to close it when communication has failed.
Keep Alives are most needed by clients with long-duration connections and little activity, such as Telnet, or some implementations of Chat. Here is a link describing a typical scenario http://www.timeshare400.com/support.htm.
There can be a philosophical discussion whether the application versus some communication layer (like yours) sends and processes keep-alive messages. Also whether they should be sent in both directions, or just one. In my opinion, the communication layer should do it if by doing so it guarantees to the application that the communication channel (socket) is open end-to-end. But as this does not necessarily guarantee that the remote Party is awake to receive the message, application-level keep-alives may be preferred.
There are instances where a client program may want to send 1 or several 1000 messages to the EchoServer routine. Furthermore, when a connection is made to the Server, and a message is sent, the client closes its connection afterwards. In your EchoServer example, in the SocketServer.AddListener routine, you set backLog to 50 and acceptThreads to 3. If the number of threads needed exceeds 3, does SocketServer increase its Thread numbers to handle multiple messages coming in? If I want to handle several 1000 messages, should I increase the "acceptThreads"?
AcceptThreads is the number of threads that accepts socket connection requests. Acceptthreads does not increase or decrease: it keeps and AcceptAsync waiting for socket connections. When a connection request arrive, if does the accept, call OnConnected and call AcceptAsync again wait for another request.
Thanks Andre - so if I have potentially 1 - 1000 client connections, should I increase the acceptThreads to be 100?
No, your acceptThread count (X) can be 1, 2, ... N. The problem is, if all the 1000 clients connects at the "same time", the first X will be accepted, others will be waiting for accept (BackLock count) and others will be blocked.