// npc.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "npc.h"

#include <windows.h> 
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <process.h>

#define BUFSIZE 512


#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 唯一的应用程序对象

CWinApp theApp;

using namespace std;

void StartThreadProc();
unsigned WINAPI WorkProc(LPVOID lpParam);

void StartThreadProc()
{
	Sleep(3000);
	// 开30个线程;
	int nThreadCount = 60;
	for ( int i = 0; i < nThreadCount; i++ )
	{
		HANDLE hThread = NULL;
		unsigned int dwThreadId = 0;
		hThread = (HANDLE)_beginthreadex(NULL, 0, WorkProc, NULL, NULL, &dwThreadId);
		CloseHandle(hThread);
	}
}

unsigned WINAPI WorkProc(LPVOID lpParam)
{
	HANDLE hPipe; 
	DWORD dwThreadId = GetCurrentThreadId();
	//LPTSTR lpvMessage=TEXT("Default message from client."); 
	TCHAR lpvMessage[MAX_PATH] = {0};
	_stprintf_s(lpvMessage, _T("Default message from client[%ld]"), dwThreadId);
	TCHAR  chBuf[BUFSIZE]; 
	BOOL   fSuccess = FALSE; 
	DWORD  cbRead, cbToWrite, cbWritten, dwMode; 
	LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe"); 

	// Try to open a named pipe; wait for it, if necessary. 

	while (1) 
	{ 
		hPipe = CreateFile( 
			lpszPipename,   // pipe name 
			GENERIC_READ |  // read and write access 
			GENERIC_WRITE, 
			0,              // no sharing 
			NULL,           // default security attributes
			OPEN_EXISTING,  // opens existing pipe 
			0,              // default attributes 
			NULL);          // no template file 

		// Break if the pipe handle is valid. 

		if (hPipe != INVALID_HANDLE_VALUE) 
			break; 

		// Exit if an error other than ERROR_PIPE_BUSY occurs. 

		if (GetLastError() != ERROR_PIPE_BUSY) 
		{
			_tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() ); 
			return -1;
		}

		// All pipe instances are busy, so wait for 20 seconds. 

		if ( ! WaitNamedPipe(lpszPipename, 20000)) 
		{ 
			printf("Could not open pipe: 20 second wait timed out."); 
			return -1;
		} 
	} 

	// The pipe connected; change to message-read mode. 

	dwMode = PIPE_READMODE_MESSAGE; 
	fSuccess = SetNamedPipeHandleState( 
		hPipe,    // pipe handle 
		&dwMode,  // new pipe mode 
		NULL,     // don't set maximum bytes 
		NULL);    // don't set maximum time 
	if ( ! fSuccess) 
	{
		_tprintf( TEXT("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() ); 
		return -1;
	}

	// Send a message to the pipe server. 

	cbToWrite = (lstrlen(lpvMessage)+1)*sizeof(TCHAR);
	_tprintf( TEXT("Sending %d byte message: \"%s\"\n"), cbToWrite, lpvMessage); 

	for (int i = 0; i <1000; i++)
	{
		fSuccess = WriteFile( 
			hPipe,                  // pipe handle 
			lpvMessage,             // message 
			cbToWrite,              // message length 
			&cbWritten,             // bytes written 
			NULL);                  // not overlapped 

		if ( ! fSuccess) 
		{
			_tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError() ); 
			return -1;
		}

		printf("\nMessage sent to server, receiving reply as follows:\n");

		do 
		{ 
			// Read from the pipe. 

			fSuccess = ReadFile( 
				hPipe,    // pipe handle 
				chBuf,    // buffer to receive reply 
				BUFSIZE*sizeof(TCHAR),  // size of buffer 
				&cbRead,  // number of bytes read 
				NULL);    // not overlapped 

			if ( ! fSuccess && GetLastError() != ERROR_MORE_DATA )
				break; 

			_tprintf( TEXT("\"%s\"\n"), chBuf ); 
		} while ( ! fSuccess);  // repeat loop if ERROR_MORE_DATA 

		if ( ! fSuccess)
		{
			_tprintf( TEXT("ReadFile from pipe failed. GLE=%d\n"), GetLastError() );
			return -1;
		}

		Sleep(100);
	}

	printf("\n<End of message, press ENTER to terminate connection and exit>");
	_getch();

	CloseHandle(hPipe); 

	return 0; 
}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// 初始化 MFC 并在失败时显示错误
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: 更改错误代码以符合您的需要
		_tprintf(_T("错误: MFC 初始化失败\n"));
		nRetCode = 1;
	}
	else
	{
		// TODO: 在此处为应用程序的行为编写代码。
		StartThreadProc();
		system("pause");
	}

	return nRetCode;
}
