Отчет_ompimpod8
.doc
МИНИСТЕРСТВО ОБРАЗОВАНИЯ РЕСПУБЛИКИ БЕЛАРУСЬ
УЧРЕЖДЕНИЕ ОБРАЗОВАНИЯ
ГОМЕЛЬСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ ИМЕНИ П. О. СУХОГО
Факультет автоматизированных и информационных систем
Кафедра «Информационные технологии»
ОТЧЕТ ПО ЛАБОРАТОРНОЙ РАБОТЕ № 8
по дисциплине «Основы мультиpпрограммной и мультипроцессной обработки данных»
на тему: «Взаимодействие между приложениями»
Выполнил: студент гр. ИТ-31
И.С. Одинцов
Принял: ассистент
И.Л. Стефановский
Дата сдачи отчета: _____________________
Дата допуска к защите: _____________________
Дата защиты: _____________________
Гомель 2011
Цель: разработать модель клиент-сервер.
Задание.
Разработать модель сервер, принимающий от клиентов регулярные выражения (согласно варианта) и выполняющий их вычисление. Клиенту возвращается удовлетворяет ли переданное выражение заданному языку или нет. Обработку запросов от клиентов реализовать с использованием пула
потоков.
6. Входной язык содержит последовательность вызовов процедур, разделенных символом;(точка с запятой). Вызов процедуры должен состоять из имени процедуры и списка
параметров. В качестве параметров могут выступать идентификаторы, строковые константы, заключенные в двойные кавычки и одиночные символы, заключенные в одинарные кавычки.
Текст программы
Реализация средствами .Net
Клиент
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
namespace ompipod8_client
{
public partial class client_main : Form
{
public client_main()
{
InitializeComponent();
}
private void button_send_Click(object sender, EventArgs e)
{
NamedPipeClientStream ClientPipe = new NamedPipeClientStream(".", "ompimpod8_server_pipe", PipeDirection.Out);
ClientPipe.Connect();
StreamWriter sw = new StreamWriter(ClientPipe);
sw.AutoFlush = true;
sw.WriteLine(Process.GetCurrentProcess().Id.ToString() + '\n' + editor.Text);
ClientPipe.Close();
NamedPipeServerStream ServerPipe = new NamedPipeServerStream("ompimpod8_server_pipe_" + Process.GetCurrentProcess().Id.ToString(), PipeDirection.In);
Enabled = false;
ServerPipe.WaitForConnection();
StreamReader sr = new StreamReader(ServerPipe);
string s = sr.ReadLine();
Enabled = true;
//MessageBox.Show(s+"|");
if (s != "True") MessageBox.Show("Ошибок нет.");
else
MessageBox.Show("Обнаружены ошибки.");
ServerPipe.Disconnect();
ServerPipe.Close();
}
private void editor_TextChanged(object sender, EventArgs e)
{
button_send.Enabled = editor.Text.Length > 0;
}
}
}
Сервер
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.IO.Pipes;
namespace ompimpod8_server
{
public struct ClientStruct
{
public string id;
public string data;
}
public partial class server_main : Form
{
Thread th, checkerTh;
NamedPipeServerStream ServerPipe = new NamedPipeServerStream("ompimpod8_server_pipe", PipeDirection.In);
List<System.Diagnostics.Process> processes = new List<System.Diagnostics.Process>();
List<ClientStruct> ClientsQueue = new List<ClientStruct>();
delegate void UpdateClientsListDel();
delegate void UpdateClientsQueueDel();
private string exited_procID;
int CurrentQueueItem;
ManualResetEvent ev = new ManualResetEvent(false);
public server_main()
{
InitializeComponent();
th = new Thread(new ThreadStart(ServerThread));
checkerTh = new Thread(new ThreadStart(ClientQueueProcessThread));
th.Start();
checkerTh.Start();
}
private bool compareIDs(ClientStruct s)
{
if (exited_procID == s.id)
{
return true;
}
else
{
return false;
}
}
private void client_exitedevent(object sender, EventArgs e)
{
exited_procID = ((System.Diagnostics.Process)sender).Id.ToString();
processes.Remove((System.Diagnostics.Process)sender);
ClientsQueue.RemoveAll(compareIDs);
UpdateClientsList();
UpdateClientsQueue();
}
private void ServerThread()
{
StreamReader sr = new StreamReader(ServerPipe);
while (true)
{
ServerPipe.WaitForConnection();
string[] temp = sr.ReadToEnd().Split('\n');
ClientStruct t;
t.id = temp[0];
string s = "";
for (int i = 1; i < temp.Length; i++)
s += temp[i];
t.data = s;
ClientsQueue.Add(t);
UpdateClientsQueue();
ServerPipe.Disconnect();
}
}
public void ClientQueueProcessThread()
{
while (true)
{
ev.WaitOne();
string[] s = ClientsQueue[0].data.Split('\n')[0].Split(';');
int count = s.Length;
if(ClientsQueue[0].data[ClientsQueue[0].data.Length - 2] == ';')count--;
NamedPipeClientStream ClientPipe = new NamedPipeClientStream(".", "ompimpod8_server_pipe_" + ClientsQueue[0].id, PipeDirection.Out,PipeOptions.WriteThrough);
ManualResetEvent[] doneEvents=null;
stringData[] strs = new stringData[count];
int j = 0;
while (j < count)
{
if(j+64<count)doneEvents = new ManualResetEvent[64];
else doneEvents = new ManualResetEvent[count-j];
for (int i = 0; i < 64 && j+i<count; i++)
{
doneEvents[i] = new ManualResetEvent(false);
strs[j + i] = new stringData(s[j + i], doneEvents[i]);
ThreadPool.QueueUserWorkItem(strs[j + i].ThreadPoolCallback, null);
}
j += 64;
WaitHandle.WaitAll(doneEvents);
}
bool haveErrors = false;
for (int i = 0; i < count; i++)
if (strs[i].haveError) haveErrors = true;
ClientPipe.Connect();
StreamWriter sw = new StreamWriter(ClientPipe);
sw.AutoFlush = true;
sw.WriteLine(haveErrors.ToString());
ClientPipe.Close();
ClientsQueue.RemoveAt(0);
UpdateClientsQueue();
if (ClientsQueue.Count > 0) ev.Set();
else ev.Reset();
}
}
private void UpdateClientsList()
{
if (clients_list.InvokeRequired)
{
UpdateClientsListDel d = new UpdateClientsListDel(UpdateClientsList);
this.Invoke(d, new object[] { });
}
else
{
clients_list.Items.Clear();
for (int i = 0; i < processes.Count; i++)
clients_list.Items.Add("Client ID = " + processes[i].Id.ToString());
}
}
private void UpdateClientsQueue()
{
if (clients_heap.InvokeRequired)
{
UpdateClientsQueueDel d = new UpdateClientsQueueDel(UpdateClientsQueue);
this.Invoke(d, new object[] { });
}
else
{
clients_heap.Items.Clear();
for (int i = 0; i < ClientsQueue.Count; i++)
clients_heap.Items.Add(ClientsQueue[i].id);
if (ClientsQueue.Count > 0) ev.Set();
}
}
private void button_startclient_Click(object sender, EventArgs e)
{
System.Diagnostics.Process p;
p = System.Diagnostics.Process.Start("ompimpod8_client.exe");
p.Exited += new EventHandler(client_exitedevent);
p.EnableRaisingEvents = true;
processes.Add(p);
UpdateClientsList();
}
private void button_closeall_clients_Click(object sender, EventArgs e)
{
for (int i = 0; i < processes.Count; i++)
processes[i].Kill();
}
private void server_main_FormClosing(object sender, FormClosingEventArgs e)
{
ServerPipe.Close();
th.Interrupt();
button_closeall_clients_Click(null, null);
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
}
class stringData
{
string str;
public bool haveError = false;
ManualResetEvent doneEvent;
public stringData(string s, ManualResetEvent _doneEvent)
{
str = s;
doneEvent = _doneEvent;
}
public void ThreadPoolCallback(Object threadContext)
{
if ((str.Length == 0) && (str[str.Length - 1] != ')'))
{
haveError = true;
}
else
{
int startIndex = str.IndexOf('('),
lastIndex = str.LastIndexOf(')'),
startIndex2 = str.LastIndexOf('('),
lastIndex2 = str.IndexOf(')');
if (startIndex < lastIndex && startIndex > 0 && lastIndex == str.Length - 1 &&
startIndex == startIndex2 && lastIndex == lastIndex2)
{
int curr = startIndex + 1;
while (curr < lastIndex)
{
string s = "";
while (str[curr] != ',' && curr < lastIndex)
{
s += str[curr];
curr++;
}
if (s.Length > 0)
{
if (s[0] == '\"' && s[s.Length - 1] != '\"') haveError = true;
if (s[0] != '\"' && s[s.Length - 1] == '\"') haveError = true;
if (s[0] == '\"' && s[s.Length - 1] == '\"')
{
int c = 0;
for (int i = 0; i < s.Length - 2; i++)
if (s[i] == '\"') c++;
if (c > 2) haveError = true;
}
if (s[0] == '\'' && s[s.Length - 1] != '\'') haveError = true;
if (s[0] != '\'' && s[s.Length - 1] == '\'') haveError = true;
if (s[0] == '\'' && s[s.Length - 1] == '\'' && s.Length != 3) haveError = true;
if (char.IsLetter(s[0]) && char.IsLetter(s[s.Length - 1]))
for (int i = 0; i < s.Length; i++)
{
if (!char.IsLetter(s[i])) haveError = true;
}
}
curr++;
}
}
else
{
haveError = true;
}
}
doneEvent.Set();
}
}
}
Реализация средствами WinApi
Клиент
#include <windows.h>
#include <stdio.h>
#include <string.h>
#define CLIENT_SEND_REQUEST_BUTTON_CLICK 30000
#define CLIENT_CLOSED 30001
#define WIN_WIDTH 400
#define WIN_HEIGHT 300
#define MAX_BUF_LEN 10000
HINSTANCE hInstance;
char szClassName[] = "ClientApp_class";
HWND hWND,hSendButton, hEditor;
HWND hServerWND;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HANDLE procHandle;
HANDLE hRecEvent;
HANDLE hEvtStartServ;
void SetDefFont(HWND AWindow)
{
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = 14;
lf.lfEscapement = 0;
lf.lfItalic = 0;
lf.lfWeight = 14;
lf.lfOrientation = 0;
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName,"Consolas");
SendMessage( AWindow, WM_SETFONT, (WPARAM)CreateFontIndirect(&lf), (LPARAM)1);
}
int WINAPI WinMain (HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
hInstance = hThisInstance;
MSG messages;
WNDCLASSEX wincl;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WndProc;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_WINDOW;
if (!RegisterClassEx (&wincl))
return 0;
hWND = CreateWindowEx (0,szClassName,"ClientApp",WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT,CW_USEDEFAULT,WIN_WIDTH,WIN_HEIGHT,HWND_DESKTOP,NULL,hThisInstance,NULL);
ShowWindow (hWND, nCmdShow);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
COPYDATASTRUCT cds;
COPYDATASTRUCT* pCds;
char *t;
char *buf;
char *out;
int strCount=0;
char eventName[30] = "Client_App_event_";
HANDLE hFileMap;
LPVOID pView;
switch (uMsg)
{
case WM_CREATE:
hSendButton = CreateWindow("button", "Отправить на сервер", WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,
WIN_WIDTH-210, WIN_HEIGHT-60, 200, 20, hWnd, (HMENU)CLIENT_SEND_REQUEST_BUTTON_CLICK, hInstance, NULL);
hEditor = CreateWindow("edit", "", WS_CHILD|WS_VISIBLE|ES_LEFT|WS_BORDER|ES_MULTILINE|WS_VSCROLL,
0, 0, WIN_WIDTH-10, WIN_HEIGHT-70, hWnd, (HMENU)NULL, hInstance, NULL);
SetDefFont(hSendButton);
SetDefFont(hEditor);
hServerWND = FindWindow(NULL, "ServerApp");
if (!hServerWND)
{
MessageBox(hWnd, "Ошибка связи!\nВозможно сервер отключен.", "ClientApp", MB_OK);
SendMessage(hWnd, WM_DESTROY, (WPARAM)NULL, (LPARAM)NULL);
}
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case CLIENT_SEND_REQUEST_BUTTON_CLICK:
strCount = SendMessage(hEditor,EM_GETLINECOUNT, 0, 0);
if(strCount==0)
{
MessageBox(hWnd, "Ошибка. Пустое поле.", "Client", MB_OK);
break;
}
buf = new char[MAX_BUF_LEN];
strcpy(buf,"");
for(int i=0;i<strCount;i++)
{
t=new char[60];
//t[0]='\0';
SendMessage(hEditor, EM_GETLINE, (WPARAM)i, (LPARAM)t);
buf = strcat(buf, t);
}
//MessageBox(hWnd, buf, "Client",MB_OK);
t=new char[10];
sprintf(t,"%d",hWnd);
strcat(eventName,t);
//MessageBox(hWnd,eventName,"Client",MB_OK);
cds.lpData = &eventName;
cds.cbData = strlen(eventName);
hRecEvent = CreateEvent(NULL, FALSE, FALSE, eventName);
hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "SharedData");
pView = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
out = (char*)pView;
sprintf(out, buf);
UnmapViewOfFile(pView);
SendMessage(hServerWND,WM_COPYDATA,(WPARAM)GetCurrentProcessId(),(LPARAM)&cds);
EnableWindow(hSendButton,FALSE);
WaitForSingleObject(hRecEvent, INFINITE);
EnableWindow(hSendButton,TRUE);
hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "SharedData");
pView = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
out = (char*)pView;
MessageBox(hWnd, out, "Client", MB_OK);
UnmapViewOfFile(pView);
/*buf = new char[MAX_BUF_LEN];
sprintf(buf,"%d",hEvtStartServ);
MessageBox(hWnd, buf,"client evHANDLE",MB_OK);*/
// hEvtStartServ = OpenEvent(EVENT_ALL_ACCESS, FALSE, "ServerStart");
//SetEvent(hEvtStartServ);
//WaitForSingleObject(hRecEvent,INFINITE);
/*hFileMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, "SharedData");
pView = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
sprintf(buf,(PTSTR)pView);
MessageBox(hWnd,buf,"client",MB_OK);
UnmapViewOfFile(pView);*/
//
break;
}
break;
case WM_COPYDATA:
//receiving request from server
hRecEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, eventName);
EnableWindow(hSendButton,TRUE);
break;
case WM_CLOSE:
case WM_DESTROY:
SendMessage(hServerWND, WM_COMMAND,(WPARAM)CLIENT_CLOSED,(LPARAM)GetCurrentProcessId());
// CloseHandle(hFileMap);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
Сервер
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <winbase.h>
#include <stdio.h>
#include "pcre.h"
#define CLIENT_SEND_REQUEST_BUTTON_CLICK1 30000
#define CLIENT_CLOSED 30001
#define SERVER_STARTCLIENT_BUTTONCLICK 30002
#define SERVER_CLOSEALLCLIENTS_BUTTONCLICK 30003
#define WIN_HEIGHT 290
#define WIN_WIDTH 440
#define MAX_CLIENTS_COUNT 20
#define MAX_QUERY_LEN 10000
struct ThreadManager {
HWND hwndParent;
};
struct ClientProcess {
HANDLE handle;
char ID[20];
};
struct ClientQueueStruct {
char data[MAX_QUERY_LEN];
char eventName[30];
HANDLE event;
char ID[20];
};
ClientProcess* ClientsList = new ClientProcess[MAX_CLIENTS_COUNT];
ClientQueueStruct *ClientsQueue = new ClientQueueStruct[MAX_CLIENTS_COUNT];
int ClientsCount = 0;
HINSTANCE hInstance;
HWND hMainWND;
char szClassName[] = "ServerApp_class";
char eventName[MAX_CLIENTS_COUNT][30];
HANDLE hEvtRecToServ[MAX_CLIENTS_COUNT];
HANDLE hEvtServerIsFree;
static int QuerysCount=0;
HANDLE hEvtServIsExist;
bool f = FALSE;
HANDLE hEvtStartServ;
HANDLE hFileMap = NULL;
HANDLE hEvtProced;
ThreadManager tm;
HWND hButtonStartClient, hButtonCloseClients, hClientsList, hClientsQueue;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
DWORD WINAPI ThreadFunc(LPVOID);
void SetDefFont(HWND AWindow)
{
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = 14;
lf.lfEscapement = 0;
lf.lfItalic = 0;
lf.lfWeight = 14;
lf.lfOrientation = 0;
lf.lfCharSet = DEFAULT_CHARSET;
strcpy(lf.lfFaceName,"Consolas");
SendMessage( AWindow, WM_SETFONT, (WPARAM)CreateFontIndirect(&lf), (LPARAM)1);
}
void UpdateClientsList()
{
SendMessage(hClientsList,LB_RESETCONTENT,0,(LPARAM)NULL);
for(int i = 0; i < ClientsCount; i++)
SendMessage(hClientsList, LB_INSERTSTRING, i, (LPARAM)ClientsList[i].ID);
}
void UpdateQuerysList()
{
SendMessage(hClientsQueue,LB_RESETCONTENT,0,(LPARAM)NULL);
for(int i = 0; i < QuerysCount; i++)
SendMessage(hClientsQueue, LB_INSERTSTRING, i, (LPARAM)ClientsQueue[i].ID);
}
void RemoveQueryFromQueue(int i)
{
for(int j=i;j<QuerysCount-1;j++)
{
ClientsQueue[j]=ClientsQueue[j+1];
}
QuerysCount--;
UpdateQuerysList();
}
void RemoveFromClients(HANDLE pid)
{
int ind=0;
for(int i=0;i<ClientsCount;i++)
if(ClientsList[i].ID==pid)ind=i;
for(int j=ind;j<ClientsCount-1;j++)
{
ClientsList[j]=ClientsList[j+1];
}
ClientsCount--;
UpdateClientsList();
}
void RemoveFromQueue(char* pid)
{
int ind=0;
for(int i=0;i<ClientsCount;i++)
if(ClientsQueue[i].ID==pid)ind=i;
RemoveQueryFromQueue(ind);
}
void CloseAllClients()
{
for(int i = 0; i < ClientsCount; i++)
TerminateProcess(ClientsList[i].handle, 0);
ClientsCount=0;
ClientsList = new ClientProcess[MAX_CLIENTS_COUNT];
UpdateClientsList();
}
int WINAPI WinMain (HINSTANCE hThisInstance,HINSTANCE hPrevInstance,LPSTR lpszArgument,int nCmdShow)
{
MSG messages;
WNDCLASSEX wincl;
RECT ScreenRect;
hInstance = hThisInstance;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WndProc;
wincl.style = CS_DBLCLKS;
wincl.cbSize = sizeof(WNDCLASSEX);
wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
wincl.hbrBackground = (HBRUSH) COLOR_WINDOW;
wincl.style = CWP_ALL;
if (!RegisterClassEx (&wincl))
return 0;
GetWindowRect(GetDesktopWindow(),&ScreenRect);
hMainWND = CreateWindowEx (0,szClassName,"ServerApp",WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,
(int)(ScreenRect.right / 2-WIN_WIDTH/2),(int)(ScreenRect.bottom / 2 - WIN_HEIGHT / 2),
WIN_WIDTH,WIN_HEIGHT,HWND_DESKTOP,NULL,hThisInstance,NULL);
ShowWindow (hMainWND, nCmdShow);
while (GetMessage (&messages, NULL, 0, 0))
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HWND hwndClient;
STARTUPINFO si;
PROCESS_INFORMATION pi;
COPYDATASTRUCT * pCds;
// HWND hwndClient;
COPYDATASTRUCT cds;
LPVOID pView;
char suffix[40];
int k;
char text[10000];
char buf[20];
static HANDLE hThread;
char * req;
char *inp;
switch (uMsg)
{
case WM_CREATE:
hEvtServIsExist = OpenEvent(EVENT_ALL_ACCESS, FALSE, "Server");
if (hEvtServIsExist)
{
MessageBox(hWnd, "Сервер уже выполняется. 2 экземпляр запрещен.", "ServerApp", MB_OK | MB_ICONSTOP | MB_SYSTEMMODAL);
PostQuitMessage(0);
}
else
hEvtServIsExist = CreateEvent(NULL, FALSE, FALSE, "Server");
hButtonStartClient = CreateWindow("button","Запустить клиент",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,
10,10,200,20,hWnd,(HMENU)SERVER_STARTCLIENT_BUTTONCLICK,hInstance,NULL);
hButtonCloseClients = CreateWindow("button","Завершить все",WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON,
220,10,200,20,hWnd,(HMENU)SERVER_CLOSEALLCLIENTS_BUTTONCLICK,hInstance,NULL);
SetDefFont(CreateWindow("static","Клиенты:",WS_CHILD|WS_VISIBLE,10,40,200,20,hWnd,(HMENU)NULL,hInstance,NULL));
SetDefFont(CreateWindow("static","Очередь на обработку:",WS_CHILD|WS_VISIBLE,220,40,200,20,hWnd,(HMENU)NULL,hInstance,NULL));
hClientsList = CreateWindow("listbox",NULL,WS_CHILD|WS_VISIBLE|LBS_STANDARD|LBS_DISABLENOSCROLL,
10,70,200,200,hWnd,(HMENU)NULL,hInstance,NULL);
hClientsQueue = CreateWindow("listbox",NULL,WS_CHILD|WS_VISIBLE|LBS_STANDARD|LBS_DISABLENOSCROLL,
220,70,200,200,hWnd,(HMENU)NULL,hInstance,NULL);
SetDefFont(hButtonStartClient);
SetDefFont(hButtonCloseClients);
SetDefFont(hClientsList);
SetDefFont(hClientsQueue);
hEvtServerIsFree = CreateEvent(NULL, FALSE, TRUE, "ServerlsFree");
hFileMap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4 * 1024, "SharedData");
hEvtStartServ = CreateEvent(NULL, FALSE, FALSE, "ServerStart");
hEvtProced = CreateEvent(NULL, TRUE, FALSE, "PROCEED_CLIENT_DATA");
tm.hwndParent = hWnd;
hThread = CreateThread(NULL, 0, ThreadFunc, &tm, 0, NULL);
break;
case WM_COPYDATA:
pCds = (COPYDATASTRUCT*)lParam;
strncpy(buf, (char*)pCds->lpData, pCds->cbData);
strcpy(ClientsQueue[QuerysCount].eventName, buf);
ClientsQueue[QuerysCount].event = OpenEvent(EVENT_ALL_ACCESS, FALSE, ClientsQueue[QuerysCount].eventName);
sprintf(ClientsQueue[QuerysCount].ID,"%d",(HANDLE)wParam);
pView = MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
inp = (char*)pView;
strcpy(ClientsQueue[QuerysCount].data, inp);
UnmapViewOfFile(pView);
//MessageBox(hWnd,ClientsQueue[QuerysCount].data,"Received data",MB_OK);
QuerysCount++;
UpdateQuerysList();
SetEvent(hEvtProced);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case SERVER_STARTCLIENT_BUTTONCLICK:
if(ClientsCount < MAX_CLIENTS_COUNT)
{
memset(&si, 0, sizeof(si));
memset(&pi, 0, sizeof(pi));
si.cb = sizeof(si);
CreateProcess(NULL, "client.exe", (LPSECURITY_ATTRIBUTES)NULL, (LPSECURITY_ATTRIBUTES)NULL,
FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
sprintf(buf, "%d", pi.dwProcessId);
ClientsList[ClientsCount].handle = pi.hProcess;
strcpy(ClientsList[ClientsCount].ID, buf);
SendMessage(hClientsList, LB_INSERTSTRING, ClientsCount, (LPARAM)(ClientsList[ClientsCount].ID));
ClientsCount++;
UpdateClientsList();
}
else
MessageBox(hMainWND, "Запущено максимальное количество клиентов", "ServerApp", MB_OK);
break;
case SERVER_CLOSEALLCLIENTS_BUTTONCLICK:
if(ClientsCount == 0)
MessageBox(hMainWND, "Нет работающих клиентов", "ServerApp", MB_OK);
else
CloseAllClients();
break;
case CLIENT_CLOSED:
//MessageBox(hWnd,"Client closed","Serve",MB_OK);
HANDLE pid = (HANDLE)lParam;
RemoveFromClients(pid);
break;
}
break;
case WM_DESTROY:
CloseAllClients();
CloseHandle(hFileMap);
CloseHandle(hEvtStartServ);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
DWORD WINAPI CheckString(PVOID lpv)
{
//MessageBox(0,"ENTRATED IN QUEUEAPC","SERVER",MB_OK);
int errCount=0,ind=0;
ind = (int)lpv;
char res[20];
char s[MAX_QUERY_LEN];
strcpy(s,ClientsQueue[ind].data);
int i=0;
bool state1, //имеет название
state2, //открыта (
state3, //закрыта )
state4, //открыта '
state5, //закрыта '
state6, //открыта "
state7, //закрыта "
state8; //
while (i<strlen(s))
{
state1 = FALSE;
state2 = FALSE;
state3 = FALSE;
state4 = FALSE;
state5 = FALSE;
state6 = FALSE;
state7 = FALSE;
while (i<strlen(s) & s[i]!=';')
{
if(errCount==0)
switch(s[i])
{
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'w':
case 'x':
case 'y':
case 'z':
if(state1==TRUE & state2==TRUE & state3==TRUE)errCount++;
else
{
if(state1==TRUE & state2==TRUE & state4==TRUE & state8==TRUE)errCount++;
if(state1==FALSE)state1=TRUE;
if(state4==TRUE)state8=TRUE;
}
break;
case '\'':
if(state1==TRUE & state2==TRUE & state4==TRUE & state8==TRUE)state5=TRUE;
else errCount++;
break;
case '\"':
if(state1==TRUE & state2==TRUE & state6==FALSE)state6=TRUE;
if(state1==TRUE & state2==TRUE & state6==TRUE &state7==FALSE)state7=TRUE;
if(state6==TRUE & state7==TRUE)errCount++;
break;
case '(':
if(state1==TRUE & state2==FALSE & state3==FALSE & state4==FALSE & state6==FALSE)state2=TRUE;
else errCount++;
break;
case ')':
if(state1==TRUE & state2==TRUE & state3==FALSE)
{
state3=TRUE;
break;
}
if(state1==TRUE & state2==FALSE)errCount++;
if(state1==TRUE & state2==TRUE & state3==TRUE & state4==FALSE & state6==FALSE)errCount++;
break;
case ',':
if(state1==FALSE | state2==FALSE & state3==FALSE)errCount++;
if(state1==TRUE & state2==TRUE & state3==TRUE)errCount++;
if(state1==TRUE & state2==TRUE & state3==FALSE & state4==TRUE & state5==FALSE & state8==FALSE)state8==FALSE;
if(state1==TRUE & state2==TRUE & state3==FALSE & state4==TRUE & state5==FALSE & state8==TRUE)errCount;
break;
default:
break;
}
i++;
}
i++;
}
if(state1==FALSE | state2==FALSE | state3==FALSE)errCount++;
if(errCount>0)sprintf(res,"Обнаружены ошибки");
else sprintf(res,"Ошибок не обнаружено");
LPVOID pView;
pView = MapViewOfFile(hFileMap, FILE_MAP_WRITE, 0, 0, 0);
char* out = (char*)pView;
sprintf(out, res);
UnmapViewOfFile(pView);
RemoveQueryFromQueue(ind);
//QuerysCount--;
//UpdateQuerysList();
//char ff[5];
//sprintf(ff,"%d",ClientsQueue[ind].event);
//MessageBox(0,ff,"Server EC",MB_OK);
SetEvent(ClientsQueue[ind].event);
// return 0;
}
DWORD WINAPI ThreadFunc(LPVOID lpv)
{
while(1)
{
WaitForSingleObject(hEvtProced,INFINITE);
//char f[5];
//sprintf(f,"%d",QuerysCount);
//MessageBox(0,f,"server qc",MB_OK);
for(int i=0;i<QuerysCount;i++)
{
//QueueUserAPC(CheckString, GetCurrentThread(), (ULONG_PTR)i);
//MessageBox(0,(char*)&i,"Server",MB_OK);
QueueUserWorkItem(CheckString,(PVOID)i,WT_EXECUTELONGFUNCTION);
}
ResetEvent(hEvtProced);
}
return 0;
}
Реализация средствами Linux Api
Клиент
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/sem.h>
#include <unistd.h>
char message[512];
char buf[sizeof(message)];
/// CLIENT
using namespace std;
int main()
{
int sock;
sockaddr srvr_name;
char buf[512];
int bytes_read;
puts("Input program code:");
gets(message);
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if(sock < 0)
{
perror("socket");
return 0;
}
srvr_name.sa_family = AF_UNIX;
strcpy(srvr_name.sa_data, "socket.soc");
if(connect(sock, &srvr_name, sizeof(srvr_name)) < 0)
{
perror("connect");
return 0;
}
send(sock, message, sizeof(message), 0);
recv(sock, buf, sizeof(message), 0);
puts(buf);
close(sock);
return 0;
}
Сервер
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/sem.h>
#include <unistd.h>
#include <stdlib.h>
int sockets[40];
pthread_t threads[10];
pthread_mutex_t mutexs[10];
bool statesthread[10];
int sockets_index[10];
static void *funct(void *arg)
{
char *chr;
chr=(char*)arg;
puts(chr);
int k=atoi(chr);
while(true)
{
pthread_mutex_init(&mutexs[k],NULL);
while(1)
{
char s[512];
int bytes_read = recv(sockets[sockets_index[k]], s, 512, 0);
if(bytes_read <= 0) break;
puts(s);
bool flag=true,dot=true;
int state=0;
int i=0;
int errCount=0;
bool state1, //имеет название
state2, //открыта (
state3, //закрыта )
state4, //открыта '
state5, //закрыта '
state6, //открыта "
state7, //закрыта "
state8; //
while (i<strlen(s))
{
state1 = false;
state2 = false;
state3 = false;
state4 = false;
state5 = false;
state6 = false;
state7 = false;
while (i<strlen(s) & s[i]!=';')
{
if(errCount==0)
switch(s[i])
{
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'w':
case 'x':
case 'y':
case 'z':
if(state1==true & state2==true & state3==true)errCount++;
else
{
if(state1==true & state2==true & state4==true & state8==true)errCount++;
if(state1==false)state1=true;
if(state4==true)state8=true;
}
break;
case '\'':
if(state1==true & state2==true & state4==true & state8==true)state5=true;
else errCount++;
break;
case '\"':
if(state1==true & state2==true & state6==false)state6=true;
if(state1==true & state2==true & state6==true &state7==false)state7=true;
if(state6==true & state7==true)errCount++;
break;
case '(':
if(state1==true & state2==false & state3==false & state4==false & state6==false)state2=true;
else errCount++;
break;
case ')':
if(state1==true & state2==true & state3==false)
{
state3=true;
break;
}
if(state1==true & state2==false)errCount++;
if(state1==true & state2==true & state3==true & state4==false & state6==false)errCount++;
break;
case ',':
if(state1==false | state2==false & state3==false)errCount++;
if(state1==true & state2==true & state3==true)errCount++;
if(state1==true & state2==true & state3==false & state4==true & state5==false & state8==false)state8==false;
if(state1==true & state2==true & state3==false & state4==true & state5==false & state8==true)errCount;
break;
default:
break;
}
i++;
}
i++;