repo: atende cliente OverLappedIO

Cliente:

#include <Windows.h>
#include <tchar.h>
#include <math.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#include "..\cliente\util.h"


DWORD WINAPI leResposta(LPVOID lpData) {
	HANDLE hPipe = (HANDLE)lpData;
	TCHAR szStr[TAM];
	DWORD dwLidos, res;


	OVERLAPPED ov;
	HANDLE hEvento;
	hEvento = CreateEvent(NULL, TRUE, FALSE, NULL); //ultimo NULL evento local à thread não peciso de nome

	do {
		ZeroMemory(&ov, sizeof(ov));
		ov.hEvent = hEvento;
		//ResetEvent(hEvent);

		res = ReadFile(hPipe, szStr, TAM, &dwLidos, &ov); //nao fico à espera agora, fica agendada a operação
		if (res) {
			_tprintf(_T("foi realizada de imediato...\n"));
		}
		if (!res && GetLastError() == ERROR_IO_PENDING) { //proteção
			_tprintf(_T("a aguardar informação...\n"));
			/* .... */
			WaitForSingleObject(ov.hEvent, INFINITE);
			GetOverlappedResult(hPipe, &ov, &dwLidos, FALSE);
		}
		_tprintf(_T("Recebi: %s (%d)\n"), szStr, dwLidos);
	} while (_tcscmp(szStr, _T("SAIR")) != 0);
	
	return 0;
}


int _tmain(int argc, TCHAR* argv[]) {
	HANDLE hPipe;
	TCHAR szStr[TAM];
	DWORD dwEscritos;

#ifdef UNICODE 
	_setmode(_fileno(stdin), _O_WTEXT);
	_setmode(_fileno(stdout), _O_WTEXT);
	_setmode(_fileno(stderr), _O_WTEXT);
#endif


	while (1) {
		//ligar ao servidor	
		hPipe = CreateFile(NOME_PIPE,
			GENERIC_READ | GENERIC_WRITE,
			0,
			NULL,
			OPEN_EXISTING,
			FILE_FLAG_OVERLAPPED,
			NULL);
		if (hPipe != INVALID_HANDLE_VALUE) {
			break;

		}
		if (!WaitNamedPipe(NOME_PIPE, 10000)) { //espera 10 segundos
			_tprintf(_T("[erro] named pipe nao existe "));
		}
	}

	//thread para ler resposta
	HANDLE hThread;
	DWORD dwTid;
	hThread = CreateThread(NULL, 0, leResposta, (LPVOID)hPipe, 0, &dwTid);

	OVERLAPPED ov;
	HANDLE hEvento;
	hEvento = CreateEvent(NULL, TRUE, FALSE, NULL);

	//thread inicial
	do {
		_tprintf(_T("TEXTO: "));
		if (_fgetts(szStr, TAM, stdin) == NULL) {
			break;
		}
		szStr[_tcslen(szStr) - 1] = _T('\0');

		ZeroMemory(&ov, sizeof(ov)); //limpar
		ov.hEvent = hEvento; //atribuir
		//ResetEvent(hEvent)//nao é necessário

		WriteFile(hPipe, szStr, ((DWORD)_tcslen(szStr) + 1) * sizeof(TCHAR), &dwEscritos, &ov); //envia info para o servidor, e não bloqueia. dwEscritos total de bytes escritos
		//devia verificar e
//true correu bem																								//true: correu bem
		//false: correu mal
		//getpasteerror, que a oepração foi agendada

		/* .. podemos fazer o que quiseremos não é tão critico.. */
		WaitForSingleObject(ov.hEvent, INFINITE);//esperar que o evento seja assinalado
		GetOverlappedResult(hPipe, &ov, &dwEscritos, FALSE); //esperar que o write foi concluido. dwEscritos verificar se o numero de bytes foram escritos
		_tprintf(_T("Enviei: %s (%d)\n"), szStr, dwEscritos);
	} while (_tcscmp(szStr, _T("SAIR")) != 0);
	return 0;
}

Servidor:

#include <Windows.h>
#include <tchar.h>
#include <math.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <time.h>
#include "..\cliente\util.h"


DWORD WINAPI atendeCliente(LPVOID lpData) {
	HANDLE hPipe = (HANDLE)lpData;
	TCHAR szStr[TAM];
	DWORD dwLidos, dwEscritos;

	_tprintf(_T("Cliente ligado...\n"));
	while (1) {
		if (!ReadFile(hPipe, szStr, TAM, &dwLidos, NULL)) { //lê pedido..
			break;
		}
		_tprintf(_T("Recebi: %s (%d)\n"), szStr, dwLidos); 
		CharUpperBuff(szStr, dwLidos/sizeof(TCHAR)); //processa
		WriteFile(hPipe, szStr, dwLidos, &dwEscritos, NULL); //envia resposta
		_tprintf(_T("Enviei: %s (%d)\n"), szStr, dwEscritos);
	}
	_tprintf(_T("O cliente desligou...\n"));
	FlushFileBuffers(hPipe);
	DisconnectNamedPipe(hPipe);
	CloseHandle(hPipe);
	return 0;
}

int _tmain(int argc, TCHAR* argv[]) {
	HANDLE hPipe;
	DWORD dwTid;

#ifdef UNICODE 
	_setmode(_fileno(stdin), _O_WTEXT);
	_setmode(_fileno(stdout), _O_WTEXT);
	_setmode(_fileno(stderr), _O_WTEXT);
#endif
	
	while (1) {
		//cada vez que um cliente se ligar é criada uma nova thread
		hPipe = CreateNamedPipe(
			NOME_PIPE, 
			PIPE_ACCESS_DUPLEX,
			PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 
			PIPE_UNLIMITED_INSTANCES, 
			BUFFSIZE, 
			BUFFSIZE, 
			10000, 
			NULL);
		if (ConnectNamedPipe(hPipe, NULL)) {
			CreateThread(NULL, 0, atendeCliente, (LPVOID)hPipe, 0, &dwTid);
		}
	}
	return 0;
}

Util:

#define TAM 100
#define NOME_PIPE TEXT("\\\\.\\pipe\\teste")
#define BUFFSIZE 1024
Tags : ,

0 thoughts on “repo: atende cliente OverLappedIO”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.