TCP Question

Posted by Eir on Fri 28 Feb 2014 09:20 PM — 6 posts, 29,044 views.

#0
Hey just want to get an overall picture here. When you open a TCP connection to the remote host (e.g. a "World") you then have to enter a loop to read into a buffer what you get on the network and display what's in the buffer to the client window. But, how do you know when to stop reading? Wouldn't it just block since the remote host never closes the connection?
Australia Forum Administrator #1
This is largely answered here:

Template:post=6554
Please see the forum thread: http://gammon.com.au/forum/?id=6554.


In brief, you don't stop reading. You read what is available (which may well be nothing) and display it, if possible. Then you process user input (typing) and then check if something (more) has arrived.

Quote:

Wouldn't it just block since the remote host never closes the connection?


You do a non-blocking read. eg.

  • Ask server how much data it has. (eg. 50 bytes)
  • Read (say) 50 bytes
  • Do other stuff, then repeat the above
#2
Thanks Nick.

In Windows, (Winsock2/Ws2_32.lib) there's several modes of socket operation (this list isn't meant to be all-inclusive):
  1. Blocking Sockets:send and recv would block.
  2. Non-Blocking Sockets:send and recv return E_WOULDBLOCK, and select is used to determine which sockets are ready.
  3. Asynchronous Sockets: Using WSAEventSelect sockets signal events (and event handlers would be used to react to these events).
  4. Overlapped Sockets: Using WSASend and WSARecv.



Trying to make my way through the source code, but it's not readily obvious to me what we're using here. Also, what's with all the
Quote:
But does it get goat's blood out?


Further, not sure if it's intentional, but when I load this up in VS I just see a huge list of source files. I.E. things are not broken up in the normal Header Files, Resource Files, etc. that I would have expected to see in the IDE.
Amended on Wed 05 Mar 2014 07:17 PM by Eir
Australia Forum Administrator #3
I use (as I recall, I started writing this quite a while back):

Quote:

Asynchronous Sockets: Using WSAEventSelect sockets signal events (and event handlers would be used to react to these events).


Incoming text is handled here (in worldsock.cpp):


void CWorldSocket::OnReceive(int nErrorCode)
{
	m_pDoc->ProcessPendingRead();
}


That ends up calling:


void CMUSHclientDoc::ReceiveMsg()


Quote:

Trying to make my way through the source code, but it's not readily obvious to me what we're using here. Also, what's with all the
Quote:
But does it get goat's blood out?


It's an old joke. It's what you say to cleaning products salesmen. "Oh yes, very interesting, but does it get goat's blood out?".

Quote:

Further, not sure if it's intentional, but when I load this up in VS I just see a huge list of source files. I.E. things are not broken up in the normal Header Files, Resource Files, etc. that I would have expected to see in the IDE.


It looks OK on my IDE but that is fairly old (Visual Studio 6.0).
#4
Thanks for the replies. I've learned a lot from you in a short time. Sorry for this rather long winded post.

Quote:
It looks OK on my IDE but that is fairly old (Visual Studio 6.0).

I tried it in both VS2010 and VS2012. I don't have any experience with VS 6.0. No offense but I'm probably a lot younger than you :)

I got it resolved, though. The issue was I had to click the "Show all Files" button above the Solution Explorer.

I would provide pictures, but I'm not sure those are supported by this forum.

Apparently, by default VS2010 & 2012 shows some "filters" view, which are essentially virtual folders to organize files in any arbitrary manner you want (which is completely separate from the physical storage structure). The project had no filters that I could see so it looked a bit strange using that view.

Anyways, I trekked through the code starting at the worldsock.cpp you mentioned. I found that you're extending the CAsyncSocket class with the CWorldSocket class. I looked up the former class on the MSDN and found that it is part of the Microsoft Foundation Class (MFC) library (I would provide a link but the MSDN links change so frequently it would probably be a dead link by the time someone else looked up this thread). Which essentially encapsulates the Win32 API commands into an object. According to Wikipedia MFC has been around since at least the early 90's in one flavor or another. I personally don't have a lot of experience with it.

With the raw Win32 API (not using MFC) I would have probably initiated the WSAWStartup (e.g. loaded the Ws2_32.dll) in the WM_CREATE message of the window process. Then used WSAAsyncSelect to request windows (the os) to send message events pertaining to that socket to the window's handle. Processing those messages in the window process via the WM_SOCKET message. I presume that under the hood the MFC classes are handling all this.

I don't know much about the specifics of ANSI Color commands, telnet commands, or the Mud Client Compression Protocol.

If I were to try to put this in my own words, essentially you load an array of bytes (char) into a buffer that you read in from the network socket. Each of these elements of the buffer array corresponds to an integer value that can map to an ASCII character that can be output to the client window. Are these ANSI codes, telnet commands, etc. values outside the normal ANSI chart, or how do you even go about interpreting them?
Australia Forum Administrator #5
Quote:

I found that you're extending the CAsyncSocket class with the CWorldSocket class. ...


I think you have to, to override the handling of incoming text. (The base class would ignore it).

Quote:

Each of these elements of the buffer array corresponds to an integer value that can map to an ASCII character that can be output to the client window. Are these ANSI codes, telnet commands, etc. values outside the normal ANSI chart, or how do you even go about interpreting them?


Er, well, it goes through a "state machine". I have a post about those:

http://www.gammon.com.au/statemachine

You have to consider that a packet might be a single byte, or break (stop) at a non-obvious boundary, so the state machine has to handle all that. For example, an ESC character (hex 0x1B) probably introduces an ANSI escape sequence (like a colour change).

Quote:

No offense but I'm probably a lot younger than you ...


Probably. No offence taken. I just have chosen not to spend the thousands of dollars that Microsoft charges (in Australia) to upgrade their products, particularly when the current one works.