Prev: Is this UTF-8 regular expression semantically correct?
Next: Newcomer's CAsyncSocket example: trouble connecting with other clients
From: stephen park on 13 May 2010 14:53 > I don't know what Joe's program is, but the above is correct when you > are talking to a telnet-like like server. I have no reason to > question Joe's CAsyncServer, but I have not try it to see what it > suppose to do for you. > > What part are you trying to make work? What are you looking for? > > What I would do is begin with the basics of writing a TTY client. If > you are just learning sockets, you need to begin with the > basics, which comes with "mistakes" and trial and error process. > > Try this TTY() function: > > void tty(String ^hostname, int port) > { > > Console::WriteLine("* Connecting"); > > TcpClient^ c; > > try { > c = gcnew TcpClient(hostname,port); > } catch(SocketException ^e) { > Console::WriteLine(L"- Connect Error {0}",e->ErrorCode); > Console::ReadKey(); > return; > } > > // use 100ms timeout for reader > c->Client->ReceiveTimeout = 100; > > array<Byte>^ bytes = gcnew array<Byte>(1024); > NetworkStream ^cio = c->GetStream(); > > while (1) { > if (Console::KeyAvailable) { > ConsoleKeyInfo^ key = Console::ReadKey(true); > if (key->Key == ConsoleKey::Escape) break; > try { > cio->WriteByte(key->KeyChar); > } catch( Exception ^e) { > break; > } > } > try { > int nBytes = c->Client->Receive( bytes ); > for (int i=0; i < nBytes; i++) { > Console::Write("{0}",(wchar_t)bytes[i]); > } > } catch( SocketException ^e) { > if (e->ErrorCode == 10054) { > Console::WriteLine(L"! Disconnect"); > break; > } > } > } > c->Close(); > Console::WriteLine("* Closed"); > Console::ReadKey(); > > } Interesting - this code doesn't work either. Dr. Newcomer's server says it got a connection, but when I type stuff in nothing gets sent. I can CTRL-C and then the server says its disconnected. Sooo ... apparently nothing is getting sent? I did try calling the .net versions of shutdown() and the NetworkStream class even has a flush() function, although the doc says that its reserved for future use. I called it anyway in my code but still nothing got sent. Interestingly enough, if I try telnetting to Dr. Newcomer's server I get the same result as the tty code above - it says its connected, but nothing gets sent? I could type stuff in, then hit Ctrl-D, Ctrl-G, whatever Ctrl combo that might hopefully say I'm done sending stuff, but nothing goes ...
From: stephen park on 13 May 2010 15:09 > I don't know what Joe's program is, but the above is correct when you > are talking to a telnet-like like server. I have no reason to > question Joe's CAsyncServer, but I have not try it to see what it > suppose to do for you. > > What part are you trying to make work? What are you looking for? > > What I would do is begin with the basics of writing a TTY client. If > you are just learning sockets, you need to begin with the > basics, which comes with "mistakes" and trial and error process. > > Try this TTY() function: > > void tty(String ^hostname, int port) > { > > Console::WriteLine("* Connecting"); > > TcpClient^ c; > > try { > c = gcnew TcpClient(hostname,port); > } catch(SocketException ^e) { > Console::WriteLine(L"- Connect Error {0}",e->ErrorCode); > Console::ReadKey(); > return; > } > > // use 100ms timeout for reader > c->Client->ReceiveTimeout = 100; > > array<Byte>^ bytes = gcnew array<Byte>(1024); > NetworkStream ^cio = c->GetStream(); > > while (1) { > if (Console::KeyAvailable) { > ConsoleKeyInfo^ key = Console::ReadKey(true); > if (key->Key == ConsoleKey::Escape) break; > try { > cio->WriteByte(key->KeyChar); > } catch( Exception ^e) { > break; > } > } > try { > int nBytes = c->Client->Receive( bytes ); > for (int i=0; i < nBytes; i++) { > Console::Write("{0}",(wchar_t)bytes[i]); > } > } catch( SocketException ^e) { > if (e->ErrorCode == 10054) { > Console::WriteLine(L"! Disconnect"); > break; > } > } > } > c->Close(); > Console::WriteLine("* Closed"); > Console::ReadKey(); > > } Interesting - this code doesn't work either. Dr. Newcomer's server says it got a connection, but when I type stuff in nothing gets sent. I can CTRL-C and then the server says its disconnected. Sooo ... apparently nothing is getting sent? I did try calling the .net versions of shutdown() and the NetworkStream class even has a flush() function, although the doc says that its reserved for future use. I called it anyway in my code but still nothing got sent. Interestingly enough, if I try telnetting to Dr. Newcomer's server I get the same result as the tty code above - it says its connected, but nothing gets sent? I could type stuff in, then hit Ctrl-D, Ctrl-G, whatever Ctrl combo that might hopefully say I'm done sending stuff, but nothing goes ...
From: Hector Santos on 13 May 2010 17:23 Stephen, It does work. That is why I gave you other host names and ports to try it. Its a simple "Dump Terminal" client application. Not sure what exactly you are looking for? How to make Joe's code work? I will have try its code to explain whats going on. What I am trying to emphasis to you, is that don't get stuck with one trying to figure out a server is not working for you. Try to learn the basics about sockets. Once you feel comfortable then you can use other codes that does most of the work for you, like Joe's code and know you would be better equip to figure out what the issue is. But the TTY() function is basic client dumb terminal framwork that does WORK, again, try it against any telnet-like server that provides output and input for you. Here is an update to the tty() that leverages the .NET asynchronous functional of the Available property and introduces LocalEcho and LineFeed concepts in typical TTY() frameworks: void tty(String ^hostname, int port = 23) { Console::WriteLine("* Connecting to {0}:{1}",hostname, port); TcpClient^ c; try { c = gcnew TcpClient(hostname,port); } catch(SocketException ^e) { Console::WriteLine(L"- Connect Error {0}",e->ErrorCode); return; } bool LocalEcho = true; // site dependent bool LineFeed = true; // site dependent array<Byte>^ bytes = gcnew array<Byte>(4*1024); NetworkStream ^cio = c->GetStream(); while (1) { if (Console::KeyAvailable) { ConsoleKeyInfo^ key = Console::ReadKey(true); if (key->Key == ConsoleKey::Escape) break; try { if (LocalEcho) { Console::Write((wchar_t)key->KeyChar); } cio->WriteByte(key->KeyChar); if (LineFeed && key->KeyChar == '\r') { cio->WriteByte('\n'); if (LocalEcho) Console::WriteLine(); } } catch( Exception ^e) { break; } } if (c->Available) { try { int nBytes = c->Client->Receive( bytes ); for (int i=0; i < nBytes; i++) { Console::Write("{0}",(wchar_t)bytes[i]); } } catch( SocketException ^e) { if (e->ErrorCode == 10054) { Console::WriteLine("! Disconnect"); break; } } } } c->Close(); Console::WriteLine("\n* Closed"); } But using the LocalEcho and LineFeed, it works better for some servers to display the console output and input. The TELNET software installed on all Windows applications plus every Telecommunications application has the same two options that is a per site setup. -- stephen park wrote: > Interesting - this code doesn't work either. Dr. Newcomer's server > says it got a connection, but when I type stuff in nothing gets sent. > I can CTRL-C and then the server says its disconnected. Sooo ... > apparently nothing is getting sent? > > I did try calling the .net versions of shutdown() and the > NetworkStream class even has a flush() function, although the doc says > that its reserved for future use. I called it anyway in my code but > still nothing got sent. > > Interestingly enough, if I try telnetting to Dr. Newcomer's server I > get the same result as the tty code above - it says its connected, but > nothing gets sent? I could type stuff in, then hit Ctrl-D, Ctrl-G, > whatever Ctrl combo that might hopefully say I'm done sending stuff, > but nothing goes ... >
From: Hector Santos on 13 May 2010 18:21 Ok, I downloaded and tested Joey's AsyncServer application. You're question is why you are seeing: ?.?.?.? [?] Closed Is that correct? The reason is that the socket is closed by the time the GetPeerPrefix() is called in DoClose() thus the socket peer binding information is already invalid. Here is the fix based on the idea that the peer information does not change during the duration of the connection. 1) In CONNECTS.H add a protected member: protected: CString PeerInfo; 2) In CONNECTS.CPP, add the following lines to the top and bottom of GetPeerInfo() so it looks like this: CString CConnectSoc::GetPeerPrefix() { if (PeerInfo != "") return PeerInfo; // HLS FIX CString ip; UINT port; GetPeerName(ip, port); if(ip.IsEmpty()) { /* no name */ return _T("?.?.?.? [?]"); } /* no name */ CString s; s.Format(_T("%s [%u]"), ip, port); PeerInfo = s; // HLS FIX return s; } // CConnectSoc::GetPeerPrefix In other words, once the PeerInfo is set, it no longer needs to get it again, it it good for the entire session. the IP and PORT will not ever change during this session. That will eliminate this minor logging issue. Now, again with minimum review of this code, I don't see it doing anything useful for you with a client application. Add this to test a simple "Echo" server: 1) Need the top of CONNECTS.CPP add: #define HLS_TEST_ECHO_SERVER 2) In the CConnectSoc::Receive() function, add this before the return result line: #ifdef HLS_TEST_ECHO_SERVER Send(Buf,result,0); #endif Now, you can test this with any TTY or telnet application, whatever you type, AsyncServer will echo it back. Hope this helps --- HLS stephen park wrote: >> I don't know what Joe's program is, but the above is correct when you >> are talking to a telnet-like like server. I have no reason to >> question Joe's CAsyncServer, but I have not try it to see what it >> suppose to do for you. >> >> What part are you trying to make work? What are you looking for? >> >> What I would do is begin with the basics of writing a TTY client. If >> you are just learning sockets, you need to begin with the >> basics, which comes with "mistakes" and trial and error process. >> >> Try this TTY() function: >> >> void tty(String ^hostname, int port) >> { >> >> Console::WriteLine("* Connecting"); >> >> TcpClient^ c; >> >> try { >> c = gcnew TcpClient(hostname,port); >> } catch(SocketException ^e) { >> Console::WriteLine(L"- Connect Error {0}",e->ErrorCode); >> Console::ReadKey(); >> return; >> } >> >> // use 100ms timeout for reader >> c->Client->ReceiveTimeout = 100; >> >> array<Byte>^ bytes = gcnew array<Byte>(1024); >> NetworkStream ^cio = c->GetStream(); >> >> while (1) { >> if (Console::KeyAvailable) { >> ConsoleKeyInfo^ key = Console::ReadKey(true); >> if (key->Key == ConsoleKey::Escape) break; >> try { >> cio->WriteByte(key->KeyChar); >> } catch( Exception ^e) { >> break; >> } >> } >> try { >> int nBytes = c->Client->Receive( bytes ); >> for (int i=0; i < nBytes; i++) { >> Console::Write("{0}",(wchar_t)bytes[i]); >> } >> } catch( SocketException ^e) { >> if (e->ErrorCode == 10054) { >> Console::WriteLine(L"! Disconnect"); >> break; >> } >> } >> } >> c->Close(); >> Console::WriteLine("* Closed"); >> Console::ReadKey(); >> >> } > > > Interesting - this code doesn't work either. Dr. Newcomer's server > says it got a connection, but when I type stuff in nothing gets sent. > I can CTRL-C and then the server says its disconnected. Sooo ... > apparently nothing is getting sent? > > I did try calling the .net versions of shutdown() and the > NetworkStream class even has a flush() function, although the doc says > that its reserved for future use. I called it anyway in my code but > still nothing got sent. > > Interestingly enough, if I try telnetting to Dr. Newcomer's server I > get the same result as the tty code above - it says its connected, but > nothing gets sent? I could type stuff in, then hit Ctrl-D, Ctrl-G, > whatever Ctrl combo that might hopefully say I'm done sending stuff, > but nothing goes ... >
From: stephen park on 13 May 2010 18:22
On May 13, 2:23 pm, Hector Santos <sant9...(a)gmail.com> wrote: > Stephen, > > It does work. That is why I gave you other host names and ports to try > it. Its a simple "Dump Terminal" client application. > > Not sure what exactly you are looking for? How to make Joe's code work? Yeah, ok, I guess let me explain it this way. Assumption: The Newcomer server works. Meaning, I can send it messages using either the Newcomer client or other client examples I've found. And note, I'm making an assumption, so I could be wrong and it does NOT handle incoming messages on a particular TCP port, but all experiments seem to indicate it works just fine. So, with the assumption in mind, I just want to write my own command line client that connects to the server and sends a message like, "Hi there!" which will display the received text. So far, using csocket, casyncsocket (with a gui), or TcpClient, has not worked. Assumption: I am doing something wrong. Obviously! But, what is frustrating (and this is not directed at anyone here, because you've all been very helpful) is that when I build my own command-line socket message sender using csocket or TcpClient, it doesn't work. And I'm either copying your code directly or looking at other examples on MSDN or elsewhere. It just plain doesn't work, and I'm getting very frustrated because it should! Example code on codemasters and elsewhere I see says, "Just do this!": // mfc version CSocket c; c.Create(); c.Connect( server, ip ); c.Send( data ); // can't remember the exact syntax, but you get the idea c.Close(); yet, when I run it, nothing gets sent. The server says it got a connection, then the connection closed. No message was "sent". Was it lost in the ether? Did the socket shut down without flushing the buffer? Maybe. But not a single example says I should do that. How the heck would I know that I need to do that? Ok, no problem, I'll flush the buffer by calling shutdown() or even flush(). But that doesn't work either. So everybody's suggesting things, which again, is very helpful and great, but nothing is working. Hence ... the frustration. Again, not directed at anyone (except maybe me). So, maybe what might help would be if someone could download the server found here: http://www.flounder.com/kb192570.htm and write a simple command-line (.net or mfc) example using csocket or TcpClient that sends a "hello" message to it. That would actually be a good start, because if I can't get that to work, then at least I'll know something else is up (although I've checked firewall settings, etc.) ... And why wouldn't I use the async client found on the newcomer page? Well, first off, I'd like to keep it really simple. I don't need to use threads or anything, nor do I need to use a GUI. So, that kinda rules out using casyncsocket. Surely this can be done! Densely yours, and thanks everyone for the suggestions to a socket noob ... |