Windows Socket Server Programming in MFC

Socket servers are slightly difficult to write when compared with the client sockets. A windows socket server program should wait, accept and exchange data with clients. Socket servers have to worry about the number of clients, accepting connections, receiving and sending data etc., This is tougher when compared with the client side programming. This article discusses a non-multithreaded approach to create a Windows socket program for a MFC Server.

Windows Socket Server Programming:

The first step is to create the Server and Client Socket classes, with server to Accept the connection and clients to receive the data. Then the server should be initialized with a port and made to listen for incoming connections.

Creating the client part:

  • Create a MFC AppWizard project of type Dialog based application.
  • Open the class wizard and click on the Add Class –> New button. Click
  • In the Add Class dialog, type ClientSocket and select the base class as CAsyncSocket.
  • Click the Change button to change the file name as ClientSocket.h and ClientSocket.cpp. Otherwise the files will be created as “lientsocket”.
  • Click Ok to close and the Wizard will create all the necessary files.
  • Create a handler for OnReceive in ClientSocket class as follows
void ClientSocket::OnReceive(int nErrorCode)
{
// Windows Socket Server Programming - client part sample code to receive data
TCHAR buff[4096];
CString m_strRecv;
int nRead;
nRead = Receive(buff, 4096);
switch (nRead)
{

case 0:
	Close();
	break;
case SOCKET_ERROR:
	if (GetLastError() != WSAEWOULDBLOCK)
	{
		AfxMessageBox ("Error occurred");
		Close();
	}
	break;
default:
	buff[nRead] = 0; //terminate the string
	CString szTemp(buff);
	m_strRecv += szTemp; // m_strRecv is a CString declared
	AfxMessageBox(m_strRecv);
	// in CMyAsyncSocket
	if (szTemp.CompareNoCase("bye") == 0 ) ShutDown();
}
CAsyncSocket::OnReceive(nErrorCode);
// Windows Socket Programming - client part code to receive data
}

Creating the Server Part:

  • Open the class wizard and Click on Add Class–>New button.
  • Type a class name as ServerSocket and select the base class as CAsyncSocket.
  • Click OK to close and allow the wizard to create the necessary files.
  • Include the header files ClientSocket.h in the ServerSocket.cpp file
  • Add a member variable inside  ServerSocket as follows.

ClientSocket m_sktClient;

  • Add a handler for OnAccept in ServerSocket class as follows
void SocketServer::OnAccept(int nErrorCode)
{

// Windows Socket Programming - Server part sample code to accept data
Accept(m_sktClient);
CAsyncSocket::OnAccept(nErrorCode);
}

Initializing the Server:

  • Include the file ServerSocket.h in the ProjectDialog.h file
  • Declare a member variable for the Dialog class as follows.
ServerSocket m_Server;
  • In the OnInitDialog, add the code as follows.
BOOL CNWServerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Windows Socket Programming - Server part sample code to Initialize server
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);

if (pSysMenu != NULL)
{
	CString strAboutMenu;
	strAboutMenu.LoadString(IDS_ABOUTBOX);
	if (!strAboutMenu.IsEmpty())
	{
	pSysMenu->AppendMenu(MF_SEPARATOR);
	pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
	}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Windows Socket Programming - Server part sample code to accept data
m_Server.Create(5001);
m_Server.Listen();
return TRUE; // return TRUE unless you set the focus to a control
}

Save the project, Build it. When it is executed, the program will wait for a client connection. Whenever a client connects and sends the data, this pops up a message box and shows the data.

Sample code can be downloaded from here.