Click here to Skip to main content
15,880,891 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
QuestionWhat are the basic benefits of using mmioxxxx “file” functions as opposed to “plain “ MFC CFile? Pin
Vaclav_6-Jul-11 13:34
Vaclav_6-Jul-11 13:34 
AnswerRe: What are the basic benefits of using mmioxxxx “file” functions as opposed to “plain “ MFC CFile? Pin
Mark Salsbery6-Jul-11 13:43
Mark Salsbery6-Jul-11 13:43 
GeneralRe: What are the basic benefits of using mmioxxxx “file” functions as opposed to “plain “ MFC CFile? Pin
Vaclav_6-Jul-11 15:43
Vaclav_6-Jul-11 15:43 
QuestionIOCP again Pin
csrss6-Jul-11 8:34
csrss6-Jul-11 8:34 
AnswerRe: IOCP again Pin
cmk6-Jul-11 10:38
cmk6-Jul-11 10:38 
AnswerRe: IOCP again Pin
Mark Salsbery6-Jul-11 10:56
Mark Salsbery6-Jul-11 10:56 
GeneralRe: IOCP again Pin
csrss6-Jul-11 11:11
csrss6-Jul-11 11:11 
QuestionThe code, in short Pin
csrss6-Jul-11 11:58
csrss6-Jul-11 11:58 
Here is a code, in short:

1. Extended overlapped:
struct IOContext
{
	WSAOVERLAPPED	m_Overlapped;

	enum IOOperation
	{
		IOAccept, 
		IORead, 
		IOWrite, 
		IOConnect, 
		IODisconnect, 
		IODefault,
		IOTerminate,
		IOTerminateStopService
	};
// some more data here
//................
        IOOperation		m_IOOperation;
	IOSocket		* m_pSocket; // this is wrapper class for WSA functions
	LPBYTE			m_pbIoRecvBuffer;	// recv buffer
	DWORD			m_cbIoRecvBuffer;	// currently received bytes
	DWORD			m_sbIoRecvBuffer;	// bytes to receive

	LPBYTE			m_pbIoSendBuffer;	// send buffer
	DWORD			m_cbIoSendBuffer;	// currently sent bytes
	DWORD			m_sbIoSendBuffer;	// bytes to send

	bool GrowRecvBuffer();
	bool FlushRecvBuffer();

	bool GrowSendBuffer();
	bool FlushSendBuffer();
	bool AllocSendBuffer(DWORD dwSize);
}

bool IOContext::GrowRecvBuffer()
{
	m_sbIoRecvBuffer += 2048;
	m_pbIoRecvBuffer = (LPBYTE)::realloc(m_pbIoRecvBuffer, 
										 m_sbIoRecvBuffer);
	if(m_pbIoRecvBuffer == NULL)
	{
		return false;
	}
	return true;
}

bool IOContext::FlushRecvBuffer()
{
	m_sbIoRecvBuffer = 0;
	m_cbIoRecvBuffer = 0;
	if(m_pbIoRecvBuffer)
	{
		::free(m_pbIoRecvBuffer);
		m_pbIoRecvBuffer = NULL;
	}
	return true;
}

bool IOContext::GrowSendBuffer()
{
	return true;
}

bool IOContext::FlushSendBuffer()
{
	m_cbIoSendBuffer = 0;
	m_sbIoSendBuffer = 0;
	if(m_pbIoSendBuffer)
	{
		::free(m_pbIoSendBuffer);
		m_pbIoSendBuffer = NULL;
	}
	return true;
}

bool IOContext::AllocSendBuffer(DWORD dwSize)
{
	m_sbIoSendBuffer = dwSize;
	if(m_pbIoSendBuffer)
	{
		::free(m_pbIoSendBuffer);
		m_pbIoSendBuffer = NULL;
	}
	m_pbIoSendBuffer = new BYTE[m_sbIoSendBuffer];
	return m_pbIoSendBuffer ? true : false;
}


2. Creating a worker thread, bind listen are just regular. Next is accept function, which is called when FD_ACCEPT event occurs:
int myclass::StreamAccept()
{
	int WSAStatus = 0;
	DWORD dwFlags = 0;

	IOContext * pIoContextEx = new IOContext();

	try
	{
	::RtlSecureZeroMemory(pIoContextEx, sizeof(IOContext));

	// associate our listen socket with IO port
	if(m_bCorePortUpdated == false)
	{
		this->m_pCorePort->Update(m_pCoreSocket->Socket(), (ULONG_PTR)pIoContextEx);
		m_bCorePortUpdated = true;
	}

	// this will return accepted socket
	pIoContextEx->m_pSocket = m_pCoreSocket->WSAAccept(NULL, NULL);

	// associate new socket with completion port

	this->UpdateCorePort(pIoContextEx->m_pSocket, pIoContextEx);

	// set current IO operation
	pIoContextEx->m_IOOperation = pIoContextEx->IORead;

	// prepare recv buffer
	if(pIoContextEx->m_sbIoRecvBuffer <= pIoContextEx->m_cbIoRecvBuffer)
	{
		pIoContextEx->GrowRecvBuffer();
	}

	// post initial recv and transfer control to worker thread
	WSAStatus = pIoContextEx->m_pSocket->WSARecv(pIoContextEx->m_pbIoRecvBuffer, 
												 pIoContextEx->m_sbIoRecvBuffer, 
												 &pIoContextEx->m_dwBytesTransfered, 
												 &dwFlags, 
												 &pIoContextEx->m_Overlapped);
	}
	catch(Exception &ex)
	{
		::MessageBox(0, ex.ErrorString(), NULL, 0);
	}
	if(WSAStatus == SOCKET_ERROR && ::WSAGetLastError() != ERROR_IO_PENDING)
	{
		throw Exception(::WSAGetLastError(), TEXT(__FILE__), TEXT(__FUNCTION__), __LINE__);
	}
	return WSAStatus;
}


3. At this moment control goes to worker thread, which begins this way:
	IOComPort * pIOComPort = (IOComPort *)lpParam; // wrapper class for completion ports API

	IOContext * pIOContext = NULL;	// per socket context
	IOContext * pIOContextCasted = NULL;	// per call context

	LPWSAOVERLAPPED Overlapped = NULL;
	DWORD dwBytesTransfered = 0;

	try
	{
		while(true)
		{

			BOOL bRet = pIOComPort->GetQueuedCompletionStatus(&dwBytesTransfered,
															  (PULONG_PTR)&pIOContext,
															  (LPOVERLAPPED *)&Overlapped,
															  -1);
			pIOContextCasted = (IOContext *)Overlapped;

//.......................
// some parsing here, checking for NULL's and stuff, and there is a read event:

                                case pIOContextCasted->IORead:
					{
						pIOContextCasted->m_dwBytesTransfered = dwBytesTransfered;
						OnStreamRecved(pIOContextCasted, pIOComPort);
					}
				break;

5. Then we are going to OnStreamRecved.
int myclass::OnStreamRecved(IOContext * pIoContext, IOComPort * pIoComPort)
{
	DWORD dwLastError = ERROR_SUCCESS;
	int WSAStatus = 0;

	CGuiPrintf::Inst()->PrintfAppend(TEXT("Total bytes transfered: %d\r\n"), pIoContext->m_dwBytesTransfered);
	if(pIoContext->m_dwBytesTransfered != 0)
	{
		pIoContext->m_cbIoRecvBuffer += pIoContext->m_dwBytesTransfered;
	}
	if(!LastPacket(	pIoContext->m_pbIoRecvBuffer, 
					&pIoContext->m_cbIoRecvBuffer, 
					pIoContext->m_sbIoRecvBuffer))
	{
		CGuiPrintf::Inst()->PrintfAppend(TEXT("Need to fetch more data!\r\n"));
		DWORD dwFlags = 0;
		if(pIoContext->m_sbIoRecvBuffer <= pIoContext->m_cbIoRecvBuffer)
		{
			pIoContext->GrowRecvBuffer();
		}

		pIoContext->m_IOOperation = pIoContext->IORead;

		try
		{

			WSAStatus = pIoContext->m_pSocket->WSARecv(	pIoContext->m_pbIoRecvBuffer + pIoContext->m_cbIoRecvBuffer,
														pIoContext->m_sbIoRecvBuffer - pIoContext->m_cbIoRecvBuffer, 
														&pIoContext->m_dwBytesTransfered, 
														&dwFlags, 
														&pIoContext->m_Overlapped);
		}
		catch(Exception &ex)
		{
			CGuiPrintf::Inst()->PrintfAppend(TEXT("%s\r\n"), ex.ErrorString());
		}

		if(WSAStatus == SOCKET_ERROR && ::WSAGetLastError() != WSA_IO_PENDING)
		{
			return OnStreamDefault(pIoContext, pIoComPort);
		}
		return WSAStatus;
	}

	if(m_bLogTransmition)
	{
		CGuiPrintf::Inst()->PrintfAppend(
			TEXT("CLIENT [%s : %d] SENT THIS: %s\r\n"),
			::inet_ntoa(pIoContext->m_remote), pIoContext->m_port_remote,
			(char *)pIoContext->m_pbIoRecvBuffer);
	}

	// now we are going to send something to a client, something that will 
	// indicate we have recved data, first we set up current IO operation

	::RtlSecureZeroMemory(&pIoContext->m_Overlapped, sizeof(pIoContext->m_Overlapped));
	pIoContext->m_IOOperation = pIoContext->IOWrite;

	// next we prepare some data to send

	BYTE bRes[] = " - server recieved.";
	DWORD dwRespSize = pIoContext->m_cbIoRecvBuffer + sizeof(bRes) + 1;

	pIoContext->AllocSendBuffer(dwRespSize);

	::RtlCopyMemory(pIoContext->m_pbIoSendBuffer, 
					pIoContext->m_pbIoRecvBuffer,
					pIoContext->m_cbIoRecvBuffer);

	::RtlCopyMemory(pIoContext->m_pbIoSendBuffer + pIoContext->m_cbIoRecvBuffer,
					bRes,
					sizeof(bRes));

	// now we send it all

	try
	{

		WSAStatus = pIoContext->m_pSocket->WSASend(pIoContext->m_pbIoSendBuffer, 
												   pIoContext->m_sbIoSendBuffer,
												   &pIoContext->m_dwBytesTransfered,
												   0,
												   &pIoContext->m_Overlapped);
	}
	catch(Exception &ex)
	{
		CGuiPrintf::Inst()->PrintfAppend(TEXT("%s\r\n"), ex.ErrorString());
	}

	pIoContext->FlushRecvBuffer();

	if(WSAStatus == SOCKET_ERROR && ::WSAGetLastError() != ERROR_IO_PENDING)
	{
		return OnStreamDefault(pIoContext, pIoComPort); // clean up client
	}

	return WSAStatus;
}


And in this above function everything crashes, while it tries to allocate recv buffer, it returns some 0xfefefe value, sometimes NULL, some strange things anyway Frown | :(
I am creating 100 worker (server) threads and 100 clients connections, client send simple text string to a server and server responds with another text string. But in this above function it crashes while trying to allocate some memory. I am just giving up...
011011010110000101100011011010000110100101101110
0110010101110011

AnswerRe: The code, in short Pin
Mark Salsbery6-Jul-11 13:21
Mark Salsbery6-Jul-11 13:21 
GeneralRe: The code, in short Pin
csrss6-Jul-11 14:53
csrss6-Jul-11 14:53 
GeneralRe: The code, in short Pin
Mark Salsbery6-Jul-11 15:22
Mark Salsbery6-Jul-11 15:22 
QuestionDynamic Tree Pin
john56326-Jul-11 1:28
john56326-Jul-11 1:28 
AnswerRe: Dynamic Tree Pin
Emilio Garavaglia6-Jul-11 2:19
Emilio Garavaglia6-Jul-11 2:19 
AnswerRe: Dynamic Tree Pin
Niklas L6-Jul-11 4:47
Niklas L6-Jul-11 4:47 
QuestionHow to retrieve Icon/Bitmap/HBITMAP information from CMenu? [modified] Pin
nate316-Jul-11 0:30
nate316-Jul-11 0:30 
AnswerRe: How to retrieve Icon/Bitmap/HBITMAP information from CMenu? Pin
Richard MacCutchan6-Jul-11 0:37
mveRichard MacCutchan6-Jul-11 0:37 
GeneralRe: How to retrieve Icon/Bitmap/HBITMAP information from CMenu? Pin
nate316-Jul-11 15:52
nate316-Jul-11 15:52 
QuestionRe: How to retrieve Icon/Bitmap/HBITMAP information from CMenu? Pin
David Crow6-Jul-11 3:52
David Crow6-Jul-11 3:52 
AnswerRe: How to retrieve Icon/Bitmap/HBITMAP information from CMenu? Pin
nate316-Jul-11 15:53
nate316-Jul-11 15:53 
GeneralRe: How to retrieve Icon/Bitmap/HBITMAP information from CMenu? Pin
David Crow6-Jul-11 16:55
David Crow6-Jul-11 16:55 
QuestionAt CADORecordset.Close() Application get crashed. Pin
Amrit Agr5-Jul-11 23:16
Amrit Agr5-Jul-11 23:16 
AnswerRe: At CADORecordset.Close() Application get crashed. Pin
Niklas L6-Jul-11 0:04
Niklas L6-Jul-11 0:04 
GeneralRe: At CADORecordset.Close() Application get crashed. Pin
Amrit Agr6-Jul-11 0:19
Amrit Agr6-Jul-11 0:19 
GeneralRe: At CADORecordset.Close() Application get crashed. Pin
Niklas L6-Jul-11 0:42
Niklas L6-Jul-11 0:42 
Questionwin32 dll is not working for c# application. Pin
Le@rner5-Jul-11 21:17
Le@rner5-Jul-11 21:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.