I'm attempting to build a simple listener, preferably without a Thread, but I am lost.

I have a working listener in 'console' mode but I need one that works with MFC. It should stay open indefinately - (until I send a shutdown message)

This is my initial non-working attempt. It connects and listens OK, but the Accept() function only receives the first line sent and then freezes. (using the code as shown - while and do loops edited out)

CString	clientIP = "xxx.xxx.xxx.xxx";

CSocket hsock;
hsock.Create(port,SOCK_STREAM,clientIP);
hsock.Listen(5);

char	buf[512];

// I know this is NOT correct, but I cannot figure out hwo to make it work
//while (1) { 
  CSocket tsock;
  hsock.Accept(tsock);

  int bytes = hsock.Receive(buf,sizeof(buf),0);
//  do {
    AfxMessageBox(buf);
//  }
//}

I've read thought Micro$ confusing MFC documentation on Socket, CSocket, AsyncSocket and I come away more confused that when I started. I think I need to use Archive(), but again I get lost.

Any help would be very welcome, but please, no links to the Micro$ site.

What happens when you change your code to this?

char	buf[512] = "";
CSocket tsock;
if ( hsock.Accept(tsock) == 0 )
{
[INDENT]// Error
return;[/INDENT]
}
while (1) 
{[INDENT]int bytes = tsock.Receive(buf,sizeof(buf),0);
if ( bytes == 0 ) // No data read. Close the Socket.
{
[INDENT]break;[/INDENT]
}
if ( bytes == SOCKET_ERROR )
{
[INDENT]AfxMessageBox("Error";
break;[/INDENT]
}
AfxMessageBox(buf);[/INDENT]}
tsock.Close();

Thanks WolfPack. That kind-of worked. The while loop causes the, I'm busy 'hour-glass' to sit on the page but I am getting results.

It dawned on me that a listener is simply a server without a send capability. Googling for Socket Server, returned some interesting techniques. I think I may be able to get this working now. I'll post back a working solution or MORE questions. :)

My solution - with help from my Google search results...

// Initilize the Listener - (in OnNewDocument for me)
BOOL CMFCSocketDoc::OnNewDocument() {
  ..
  // #include "MFCServer.h" in .doc.h
  // declare...  MFCServer skt_server; in ...doc.h
  skt_server.Create(port#);
  skt_server.Listen();
  return true;
}

// Create 2 new classes:
class MFCServer : public CAsyncSocket {...};
// Add this function  
void MFCServer::OnAccept(int nErrorCode) {
  // #include "MFCClient.h" in .h
  // declare... MFCClient skt_client; in .h
  Accept(skt_client);
  CAsyncSocket::OnAccept(nErrorCode);
}

class MFCClient : public CAsyncSocket {...};
// Add this function
void MFCClient::OnReceive(int nErrorCode) {
  char buff[200];
  int bytes_read = Receive(buff, 200);
  buff[bytes_read] = 0;			//terminate the string

  AfxMessageBox(buff);
  CAsyncSocket::OnReceive(nErrorCode);
}

And there you have it - A simple listener without threads.
If I did something REALLY wrong, please let me know.

I'm back :)

I incorporated the above into my program and it worked - well almost.

The computer (listener) is connected to a device that closes it's socket after an idle time of 15 sec to save on network resources. In my 'console' version, when the device comes alive, data is sent and received. - no problem.

But in the MFC version, after this idle time-out period and on the next read, it creates a 'Debug Assertion Failed' popup (sockcore.cpp, Line 117). If I then click on 'Ignore', the data is read. All additional data goes through the same cycle.

So what did I do wrong?

A few hours of testing and head scratching, and I came up with a solution. Pretty simple really...

When the device closed it's socket, it attempted to reconnect but the skt_client socket was still open and the OnAccept tried to create a new client socket. So I simply closed the socket and allowed a new one to be opened.

void MFCServer::OnAccept(int nErrorCode) {
  CAsyncSocket::OnAccept(nErrorCode);
  skt_client.Close();
  Accept(skt_client);
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.