Реализация взаимодействия через PIPE

Автор работы: Пользователь скрыл имя, 04 Мая 2014 в 11:08, курсовая работа

Краткое описание

СУБД SQLite является легковеснойвстраиваемой, это значит, что все операции с данными выполняются внутри приложения без использования сервера базы данных. Исходный код данной СУБД находится в свободном доступе. Доступ к данным в базе происходит через подключения к базе данных, которые мы открываем через вызов соответственной функции DLL.
Для взаимодействия приложения с СУБД SQLite в настоящий момент используются различные интерфейсы, такие как встроенный интерфейс SQLite,JDBC, ODBC и т.п. Однако, нет реализации интерфейса, поддерживающего взаимодействие клиента с сервером СУБД при помощи Pipeпод Windows.

Содержание

1. Исследование предметной области…….…………………….…………….…5
1.1. Постановка задачи…....…………………….…………….………………..5
1.2. Описание SQLite……….…………...…….…………….………………….7
1.2.1. Устройство и характеристики СУБД SQLite……………...….........7
1.2.2. Методы работы с базой данных……………………….…………....8
1.3. ОписаниеPIPE под Windows…………...…...…………...………………10
1.3.1. Общие понятия ………………………..…………...……………….10
1.3.2. Именованные каналы………………..……………...……………....10
1.3.3. Методы WinAPI для передачи данных…………......……………...12
2. Замысел технического решения….…………………….…………………….15
2.1. Реализация взаимодействия через PIPE…......…………………………..15
2.2. Исполнение запросов кSQLite…………......………………....………….16
3. Описание программы……………….………..…...………………...………...17
3.1. Сервер………………………………...…...……………………………….17
3.2. Клиент…………………………...…………...…………………………….21
3.3. API……………………….....…………………….………………………...22
4. Заключение……….…………………………………….…………………...…24
5. Список используемой литературы…….…………….……………………….

Прикрепленные файлы: 1 файл

Текст курсовой.docx

— 222.81 Кб (Скачать документ)

#include <string>

 

#include "atlstr.h"

 

#include "sqlite3.h"

 

#define BUFSIZE 512

using namespace std;

 

DWORD WINAPI InstanceThread(LPVOID);

VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);

sqlite3 *db = 0; // хэндл объекта  соединение к БД

char *err = 0;

int _tmain(VOID)

{

   BOOL   fConnected = FALSE;

   DWORD  dwThreadId = 0;

   HANDLE hPipe = INVALID_HANDLE_VALUE, hThread = NULL;

   LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\SamplePipe");

 

if( sqlite3_open("db1.dblite", &db) )

printf("Error in open/create DB: %s\n", sqlite3_errmsg(db));

   for (;;)

   {

      _tprintf( TEXT("\nPipe Server: Main thread awaiting client connection on %s\n"), lpszPipename);

      hPipe = CreateNamedPipe(

          lpszPipename,             // pipe name

          PIPE_ACCESS_DUPLEX,       // read/write access

          PIPE_TYPE_MESSAGE |       // message type pipe

          PIPE_READMODE_MESSAGE |   // message-read mode

          PIPE_WAIT,                // blocking mode

          PIPE_UNLIMITED_INSTANCES, // max. instances 

          BUFSIZE,                  // output buffer size

          BUFSIZE,                  // input buffer size

          0,                        // client time-out

          NULL);                    // default security attribute

 

      if (hPipe == INVALID_HANDLE_VALUE)

      {

          _tprintf(TEXT("CreateNamedPipe failed, GLE=%d.\n"), GetLastError());

          return -1;

      }

 

      fConnected = ConnectNamedPipe(hPipe, NULL) ?

         TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);

 

      if (fConnected)

      {

         printf("Client connected, creating a processing thread.\n");

     

         // Create a thread for this client.

         hThread = CreateThread(

            NULL,              // no security attribute

            0,                 // default stack size

            InstanceThread,    // thread proc

            (LPVOID) hPipe,    // thread parameter

            0,                 // not suspended

            &dwThreadId);      // returns thread ID

 

         if (hThread == NULL)

         {

            _tprintf(TEXT("CreateThread failed, GLE=%d.\n"), GetLastError());

            return -1;

         }

         else CloseHandle(hThread);

       }

      else

        // The client could not connect, so close the pipe.

         CloseHandle(hPipe);

   }

 

   return 0;

}

 

DWORD WINAPI InstanceThread(LPVOID lpvParam)

{

   HANDLE hHeap      = GetProcessHeap();

   TCHAR* pchRequest = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));

   TCHAR* pchReply   = (TCHAR*)HeapAlloc(hHeap, 0, BUFSIZE*sizeof(TCHAR));

 

   DWORD cbBytesRead = 0, cbReplyBytes = 0, cbWritten = 0;

   BOOL fSuccess = FALSE;

   HANDLE hPipe  = NULL;

 

   if (lpvParam == NULL)

   {

       printf( "\nERROR - Pipe Server Failure:\n");

       printf( "   InstanceThread got an unexpected NULL value in lpvParam.\n");

       printf( "   InstanceThread exitting.\n");

       if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);

       if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);

       return (DWORD)-1;

   }

 

   if (pchRequest == NULL)

   {

       printf( "\nERROR - Pipe Server Failure:\n");

       printf( "   InstanceThread got an unexpected NULL heap allocation.\n");

       printf( "   InstanceThread exitting.\n");

       if (pchReply != NULL) HeapFree(hHeap, 0, pchReply);

       return (DWORD)-1;

   }

 

   if (pchReply == NULL)

   {

       printf( "\nERROR - Pipe Server Failure:\n");

       printf( "   InstanceThread got an unexpected NULL heap allocation.\n");

       printf( "   InstanceThread exitting.\n");

       if (pchRequest != NULL) HeapFree(hHeap, 0, pchRequest);

       return (DWORD)-1;

   }

 

   // Print verbose messages. In production code, this should be for debugging only.

   printf("InstanceThread created, receiving and processing messages.\n");

 

   hPipe = (HANDLE) lpvParam;

 

// Loop until done reading

   while (1)

   {

      fSuccess = ReadFile(

         hPipe,        // handle to pipe

         pchRequest,    // buffer to receive data

         BUFSIZE*sizeof(TCHAR), // size of buffer

         &cbBytesRead, // number of bytes read

         NULL);        // not overlapped I/O

 

      if (!fSuccess || cbBytesRead == 0)

      {  

          if (GetLastError() == ERROR_BROKEN_PIPE)

          {

              _tprintf(TEXT("InstanceThread: client disconnected.\n"), GetLastError());

          }

          else

          {

              _tprintf(TEXT("InstanceThread ReadFile failed, GLE=%d.\n"), GetLastError());

          }

          break;

      }

 

   // Process the incoming message.

      GetAnswerToRequest(pchRequest, pchReply, &cbReplyBytes);

 

   // Write the reply to the pipe.

      fSuccess = WriteFile(

         hPipe,        // handle to pipe

         pchReply,     // buffer to write from

         cbReplyBytes, // number of bytes to write

         &cbWritten,   // number of bytes written

         NULL);        // not overlapped I/O

 

      if (!fSuccess || cbReplyBytes != cbWritten)

      {  

          _tprintf(TEXT("InstanceThread WriteFile failed, GLE=%d.\n"), GetLastError());

          break;

      }

  }

 

   FlushFileBuffers(hPipe);

   DisconnectNamedPipe(hPipe);

   CloseHandle(hPipe);

 

   HeapFree(hHeap, 0, pchRequest);

   HeapFree(hHeap, 0, pchReply);

 

   printf("InstanceThread exitting.\n");

   return 1;

}

 

VOID GetAnswerToRequest( wchar_t* pchRequest,

                         LPTSTR pchReply,

                         LPDWORD pchBytes )

{

    _tprintf( TEXT("Client Request String:\"%s\"\n"), pchRequest );

    wcout << pchRequest << _T(" (wchar_t *)") << endl;

 

    size_t origsize = wcslen(pchRequest) + 1;

    size_t convertedChars = 0;

    const size_t newsize = origsize*2;

    char *sqlreq = new char[newsize];

    wcstombs_s(&convertedChars, sqlreq, newsize, pchRequest, _TRUNCATE);

    cout <<"SQL request: "<< sqlreq << endl;

wchar_t *response;

response = L" ";

if (sqlite3_exec(db, sqlreq, 0, 0, &err))

{

printf("SQL Error: %sn", err);

sqlite3_free(err);

response = L"SQL Error";

} else response = L"Success";

    // Check the outgoing message to make sure it's not too long for the buffer.

    if (FAILED(StringCchCopy( pchReply, BUFSIZE, response )))

    {

        *pchBytes = 0;

        pchReply[0] = 0;

        printf("StringCchCopy failed, no outgoing message.\n");

        return;

    }

    *pchBytes = (lstrlen(pchReply)+1)*sizeof(TCHAR);

}

 

 

ПРИЛОЖЕНИЕ 2

CppNamedPipeClient.cpp

#pragma region Includes

#include <stdio.h>

#include <windows.h>

#include "iostream"

#pragma endregion

#include "SQLite_API.h"

 

// The full name of the pipe in the format of \\servername\pipe\pipename.

#define SERVER_NAME         L"."

#define PIPE_NAME           L"SamplePipe"

#define FULL_PIPE_NAME      L"\\\\" SERVER_NAME L"\\pipe\\" PIPE_NAME

 

#define BUFFER_SIZE     1024

 

// Request message from client to server.

#define REQUEST_MESSAGE     L"CREATE TABLE IF NOT EXISTS foo(a,b,c); INSERT INTO FOO VALUES(1,2,3); INSERT INTO FOO SELECT * FROM FOO;"

using namespace std;

 

 

int wmain(int argc, wchar_t* argv[])

{

wchar_t req_str[200];

Pipe_SERVER server(FULL_PIPE_NAME);

    // Try to open the named pipe identified by the pipe name.

int err = server.connect();

if (err == 1) {

cout << "Error while connection";

server.cleanup();

system("pause");

return 0;

}

wprintf(L"Enter Request:");

wscanf( L"%[^\r\n]", req_str );

    //

    // Send a request from client to server

    //

 

    if (server.send_data(req_str, sizeof(req_str)) !=0 ) {

cout << "error while sending data";

server.cleanup();

system("pause");

return 0;

} else {

cout << "Success in sending"<<endl;

}

 

    //

    // Receive a response from server.

    //

//

//Code from exhample

if (server.recieve_data() == 0)

wprintf(L"Recieved successfull. Data: \"%s\"\n", server.chResponse);

   

//

server.cleanup();

  

system("pause");

    return server.dwError;

}

 

 

ПРИЛОЖЕНИЕ 3

SQLite_API.h

#include <stdio.h>

#include <windows.h>

#include "iostream"

#pragma endregion

 

class Pipe_SERVER

{

private:

HANDLE hPipe;

LPCWSTR FULL_PIPE_NAME;

static const int BUFFER_SIZE = 1024;

 

public:

DWORD dwError;

TCHAR chResponse[BUFFER_SIZE]; //Answers from server

Pipe_SERVER(LPCWSTR PIPE_NAME){

hPipe = INVALID_HANDLE_VALUE;

dwError = ERROR_SUCCESS;

FULL_PIPE_NAME = PIPE_NAME;

}

 

int connect(){

while (TRUE){

hPipe = CreateFile(

FULL_PIPE_NAME,                 // Pipe name

GENERIC_READ | GENERIC_WRITE,   // Read and write access

0,                              // No sharing

NULL,                           // Default security attributes

OPEN_EXISTING,                  // Opens existing pipe

0,                              // Default attributes

NULL                            // No template file

);

if (hPipe != INVALID_HANDLE_VALUE)

{

wprintf(L"The named pipe (%s) is connected.\n", FULL_PIPE_NAME);

break;

}

 

dwError = GetLastError();

 

if (ERROR_PIPE_BUSY != dwError)

{

wprintf(L"Unable to open named pipe w/err 0x%08lx\n", dwError);

return 1;

}

 

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

if (!WaitNamedPipe(FULL_PIPE_NAME, 5000))

{

dwError = GetLastError();

wprintf(L"Could not open pipe: 5 second wait timed out.");

return 1;

}

}

// Set the read mode and the blocking mode of the named pipe. In this

// sample, we set data to be read from the pipe as a stream of messages.

DWORD dwMode = PIPE_READMODE_MESSAGE;

if (!SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL))

{

dwError = GetLastError();

wprintf(L"SetNamedPipeHandleState failed w/err 0x%08lx\n", dwError);

return 0;

}

return 0;

}

//

int send_data(wchar_t *chRequest, int length){

DWORD cbWritten;

wprintf( L"Sizeof %d of message:  %s\n",length, chRequest);

;

if (!WriteFile(

hPipe,                      // Handle of the pipe

chRequest,                  // Message to be written

length,                  // Number of bytes to write

&cbWritten,                 // Number of bytes written

NULL                        // Not overlapped

))

{

dwError = GetLastError();

wprintf(L"WriteFile to pipe failed w/err 0x%08lx\n", dwError);

return 1;

cleanup();

}

 

wprintf(L"Send %ld bytes to server: \"%s\"\n", cbWritten, chRequest);

return 0;

}

 

int recieve_data(){

BOOL fFinishRead = FALSE;

do

{

 

DWORD cbResponse, cbRead;

cbResponse = sizeof(chResponse);

 

fFinishRead = ReadFile(

hPipe,                  // Handle of the pipe

chResponse,             // Buffer to receive the reply

cbResponse,             // Size of buffer in bytes

&cbRead,                // Number of bytes read

NULL                    // Not overlapped

);

 

if (!fFinishRead && ERROR_MORE_DATA != GetLastError())

{

dwError = GetLastError();

wprintf(L"ReadFile from pipe failed w/err 0x%08lx\n", dwError);

cleanup();

return 1;

}

 

} while (!fFinishRead); // Repeat loop if ERROR_MORE_DATA

Информация о работе Реализация взаимодействия через PIPE