Click here to Skip to main content
15,895,084 members
Articles / Programming Languages / C#

Using Mailslots for Interprocess Communication

Rate me:
Please Sign up or sign in to vote.
4.83/5 (34 votes)
17 Oct 2004CPOL21 min read 147.4K   6.8K   90  
How to use mailslots to communicate between processes
/*
 *	$Header: $
 *
 *	$History: $
 */
#include "stdafx.h"
#include "SyncMailslotWriter.h"

// Construction/Destruction
CSyncMailslotWriter::CSyncMailslotWriter() : CMailslot()
{
}

CSyncMailslotWriter::~CSyncMailslotWriter()
{
}

//	Creates a connection to a mail slot.
//	Returns true on success, false on failure.
bool CSyncMailslotWriter::Connect(LPCTSTR szSlotname, LPCTSTR szServer)
{
	assert(szServer);
	assert(szSlotname);

	//	Delete any previous mail slot name
	delete m_pszSlotname;
	m_pszSlotname = new TCHAR[_MAX_PATH];
	assert(m_pszSlotname);

	//	Create our mail slot name
	_sntprintf(m_pszSlotname, _MAX_PATH, _T("\\\\%s\\mailslot\\%s"), szServer, szSlotname);
	m_pszSlotname[_MAX_PATH - sizeof(TCHAR)] = TCHAR(0);
	
	//	Now connect...
	return Connect();
}

bool CSyncMailslotWriter::Connect()
{
	//	Close any existing mail slot
	Disconnect();

	//	Now open the mail slot for overlapped I/O
	if ((m_hMailSlot = CreateFile(m_pszSlotname, 
							GENERIC_WRITE, 
							FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 
							FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, &m_overlapped)
							) != INVALID_HANDLE_VALUE)
	{
		m_overlapped.Attach(m_hMailSlot);
		return true;
	}

	return false;
}

//	Writes a message to the mail slot.
DWORD CSyncMailslotWriter::Write(BYTE *pbData, DWORD dwDataLength)
{
	assert(pbData);
	assert(dwDataLength);

	int nRetries = 2;

	while (nRetries--)
	{
		//	If the mail slot is closed attempt to reconnect to it
		if (!IsOpen() && m_pszSlotname != LPTSTR(NULL))
			Connect();

		DWORD dwWrittenLength = 0;

		if (IsOpen())
		{
			//	Write using overlapped I/O. We have to use overlapped 
			//	I/O if we want to be able to interrupt the write. If we use 
			//	synchronous I/O there's a high chance the operation will stall 
			//	inside the WriteFile call.  See 
			//	http://www.codeproject.com/win32/overlappedio.asp
			//	for a more detailed explanation.
			if (m_overlapped.Write(pbData, dwDataLength, &dwWrittenLength, m_hStopEvent) && dwWrittenLength == dwDataLength)
				//	The I/O completed so return success (true).
				return dwWrittenLength;
			else
				//	If the write failed discard it but also force a disconnect so
				//	that the next write will attempt a connection.
				Disconnect();
		}
	}

	return 0;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
I've been programming for 35 years - started in machine language on the National Semiconductor SC/MP chip, moved via the 8080 to the Z80 - graduated through HP Rocky Mountain Basic and HPL - then to C and C++ and now C#.

I used (30 or so years ago when I worked for Hewlett Packard) to repair HP Oscilloscopes and Spectrum Analysers - for a while there I was the one repairing DC to daylight SpecAns in the Asia Pacific area.

Afterward I was the fourth team member added to the Australia Post EPOS project at Unisys Australia. We grew to become an A$400 million project. I wrote a few device drivers for the project under Microsoft OS/2 v 1.3 - did hardware qualification and was part of the rollout team dealing directly with the customer.

Born and bred in Melbourne Australia, now living in Scottsdale Arizona USA, became a US Citizen on September 29th, 2006.

I work for a medical insurance broker, learning how to create ASP.NET websites in VB.Net and C#. It's all good.

Oh, I'm also a Kentucky Colonel. http://www.kycolonels.org

Comments and Discussions