pmsumner: (Default)
Add MemoryShare This Entry
And I am struggling somewhat. I started off using System.Net.Sockets.Socket and it didn't seem to do what it said on the tin. Since then I've moved on to using the TcpClient mechanism which is allegedly simpler.

I seem to be having timing issues with my wannabe telnet client. The stuff I've written works fine when I step through it, but when I let it run through on it's own, I get problems where it seems to run too fast and doesn't allow time to receive the data back from the server, despite using what I thought were blocking functions.

i.e. I expect the following from the server:
Welcome to XYZ telnet server
Username: 


When I step through, I get that fine in my return string. But when left to run, I only get the first line, so the stuff that relies on waiting for "Username: " always comes back as false.

I don't know how to work around it. My Google-fu is failing me and it's frustrating as 'owt.

Anyhow. Tomorrow is another day, and the brain may be more awake.
There are 8 comments on this entry. (Reply.)
 
posted by [identity profile] albatros.livejournal.com at 05:54am on 26/02/2009
Are you doing it as a 'finite state machine' with callbacks? (NB if you don't know what either of these are, they can be looked-up)
 
posted by [identity profile] phil99.livejournal.com at 10:38am on 26/02/2009
I'm not really doing anything FSM-ish explicitly.

I'm trying to do it procedurally (is that even a word?) - i.e. one thing after another. I know the order that I'll receive data and I know the order I need to send it.

I've a loop that says "Receive until you've got nothing left to receive" doesn't seem to do that - it seems to receive until it gets bored. I guess this is the root of the problem for me - trying to figure out what the method system.net.sockets.tcpclient.read actually does as opposed to what I think it does.
 
posted by [identity profile] phil99.livejournal.com at 11:02am on 26/02/2009
However I've since come to the conclusion that doing it asynchronously and with some form of state handling might be the way to do it.

Hrm. Problem is I'm trying to do this while being interrupted every few minutes...
 
posted by [identity profile] mooism.livejournal.com at 08:52am on 26/02/2009
Probably the different lines are being sent in different packets. Your blocking call returns as soon as the first packet appears.
 
posted by [identity profile] phil99.livejournal.com at 10:51am on 26/02/2009
I'm looping round with a:

while stream.dataAvailable
- read from stream
- convert buffer to string
wend

The problem I'm seeing is that dataAvailable doesn't always seem to true when I think it should be.
 
posted by [identity profile] mooism.livejournal.com at 11:29am on 26/02/2009
Here's what I think's happening:

1. Your pc receives a packet containing the first line.

2. Your loop runs. To begin with, there is dataAvailable (that first packet conataining the first line), so you read it in. Then there is not dataAvailable, so you stop looping.

3. Your pc receives a packet containing the second line. Now there is dataAvailable again, but you have stopped checking for it.

When you step through in the debugger, both packets have arrived by the time you hit the loop, which is why it works fine in that case.
 
posted by [identity profile] phil99.livejournal.com at 01:28pm on 26/02/2009
I think you're right. Which is a pain in the arse. Not at all how I expected these things to work.

Time for another rethink :)
 
posted by [identity profile] albatros.livejournal.com at 02:06pm on 26/02/2009
Sorry to give the impression that I've programmed for networking, but I haven't. But I do know that you shouldn't depend on your packets arriving together (and in some protocols, in sequence).

So based on that, you'll need code that collects information until it has everything it needs to do something.

Your code is fine, but only as a "gather information while it's there" routine. You'll also have to keep invoking that code, and updating internal states, until you receive enough information to act, and then pass that information on to whatever needs it in your regular app.

I expect you'll therefore need:

1. A low-level packet-gathering routine (which you have),
2. A packet interpreter, which maintains individual streams, passes on complete streams to other code, or frees expired streams. Call this a 'session manager' (for want of a better name).
4. The functionality of your program, called by the session manager.

You'll probably need to code it defensively, so you don't fill up memory, or be vulnerable to DoS attacks.

Throughout all this, I can't help wondering if there's an API or framework that already has some of this functionality?

Perhaps someone with more experience than me can tell me (and P) if I'm talking twaddle, and perhaps know of an API/framework?

May

SunMonTueWedThuFriSat
      1
 
2
 
3
 
4
5
 
6
 
7
 
8
 
9
 
10
 
11
 
12
 
13
 
14
 
15
 
16
 
17
 
18
 
19
 
20
 
21
 
22
 
23
 
24
 
25
 
26
 
27
 
28
 
29
 
30
 
31