• B правой части каждого сообщения есть стрелки и . Не стесняйтесь оценивать ответы. Чтобы автору вопроса закрыть свой тикет, надо выбрать лучший ответ. Просто нажмите значок в правой части сообщения.

  • 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

    На последнюю неделю приходится экзамен, где нужно будет показать свои навыки, взломав ряд уязвимых учебных сайтов, и добыть флаги. Успешно сдавшие экзамен получат сертификат.

    Запись на курс до 25 апреля. Получить промодоступ ...

Помоги мне с маилслотами, пожалуйста (С++)

  • Автор темы Ninoka
  • Дата начала
N

Ninoka

Итак курсовик на С++ , суть - распределенное вычисление числа.
Кратко как работает: запускается сервер, потом запускается клиент.
Клиент шлет серверу запрос через ящик, чтобы сервер посчитал ему большое число.
Сервер делает себе нити, каждая из которых считает свой маленький кусочек, потом сервер эти кусочки суммирует.
И вот то что получилось, он должен послать клиенту опять же через маил-слот (но уже другой).

Но! Не шлет!
Что характерно - отправка запроса от клиента серверу - работает нормально.
В чем проблема - не пойму уже неделю.... :)


Вот код (сразу прошу прощение, что много букв):

[codebox]// spo_lab5.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "conio.h"
#include <stdio.h>
#include <windows.h>

const int ALARM_START = 1;
const int ALARM_EXIT = 2;
//структура
struct ALARMTIME
{
int command;
int h;
int m;
int koln;
int toch;

};
struct PI
{
double pi;

};
//глобальная переменная
double pr;
double rez;

//----------------------------------------------------------------------------------------------
double MyFunc (int i)//функция вычисления, используется каждой нитью
{
int j=0;
double a=-3, b=-1;

for (j=0; j<i; j++)
{
a=a+4;
b=b+4;
}
//вычисляем кусочек Пи
pr=1/a-1/b;
printf ("rabota procesa %d, parametru a=%.1f, b=%.1f, rezult pr=%.15f \n\n", i, a, b, pr);
Sleep(20);
return pr;
}
//----------------------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
HANDLE hMail;
HANDLE hMail2;
HANDLE hThread; //описатель созданного потока

int i=0;
char MailSlotName[] = "\\\\.\\mailslot\\SPOMailslot";
char MailSlotName2[] = "\\\\.\\mailslot\\SPOMailslot2";

//структуры
ALARMTIME at;
SYSTEMTIME st;
PI otvet;

DWORD CountBytes, CountBytes2;
DWORD NextSize, NextSize2;
DWORD dwThreadId; //ID созданного потока

char MailSlotPath[] = "\\\\*\\mailslot\\SPOMailslot";
char MailSlotPath2[] = "\\\\*\\mailslot\\SPOMailslot2";
// создаем ящик от лица сервера
hMail=CreateMailslot(MailSlotName,sizeof(ALARMTIME),0,NULL);

if(hMail==INVALID_HANDLE_VALUE)//--------------------ветка клиента---------------------------
{
printf("This is client.\n");


//открываем ящик со стороны клиента
hMail = CreateFile(MailSlotPath,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if (hMail == INVALID_HANDLE_VALUE)
{
printf("Error. Can not open mailslot.\n");
return 1;
}

do // пока не выход гоняем цикл
{
printf("Select command for server:\n1 - start, 2 - close\n");
// ввод юзером параметров
scanf("%d",&at.command);
switch(at.command)
{
case ALARM_START:
printf("Vvedite vremy dly budilnika:\n");
printf("H:");
scanf("%d",&at.h);
printf("M:");
scanf("%d",&at.m);;
printf("Vvedite kolichestvo nitej:");
scanf("%d",&at.koln);;
printf("Vvedite tochnost:");
scanf("%d",&at.toch);;
break;

case ALARM_EXIT:
break;
default:
printf("Error.Bad command.\n");
}
// отправка параметров серверу
WriteFile(hMail, &at, sizeof(ALARMTIME), &CountBytes, 0);

//создание второго ящика для приемки ответа
hMail2=CreateMailslot(MailSlotName2,sizeof(PI),0,NULL);
if(hMail2==INVALID_HANDLE_VALUE)
printf("ne sozdaetsy vtoroj yashcik");

//ПОКА ТОЛЬКО ПОПЫТКА прочитать ответ от сервера
if (!GetMailslotInfo(hMail2, NULL, &NextSize2, NULL, NULL))
{
CloseHandle(hMail2);
printf("Error.Can not get info about mailslot2\n");
getch();
return 1;

}

//сюда не заходит(((
//если есть сообщение в почте
if ((NextSize2 | 0xffff0000) != MAILSLOT_NO_MESSAGE)
{
printf("zashli syda");
if (!ReadFile(hMail2,&otvet, (WORD)NextSize2, &CountBytes2, 0))
{
printf("Error.Can not receive message\n");
CloseHandle(hMail2);
getch();
return 1;
}

printf("pi= %.*f\n", at.toch, otvet.pi);
}
} while (!(at.command==2));

}
else//--------------------ветка сервера---------------------------
{
printf("This is server.\n");
ALARMTIME current_at;
bool off=true;
bool exit=false;
while(!exit)// пока не выход
{
//проверяем состояние ящика
if (!GetMailslotInfo(hMail, NULL, &NextSize, NULL, NULL))
{
CloseHandle(hMail);
printf("Error.Can not get info about mailslot\n");
return 1;
}
//если есть сообщение в почте
if ((NextSize | 0xffff0000) != MAILSLOT_NO_MESSAGE)
{
if (!ReadFile(hMail,&at, (WORD)NextSize, &CountBytes, 0))
{
printf("Error.Can not receive message\n");
CloseHandle(hMail);
return 1;
}

switch(at.command)
{
case ALARM_START:
current_at=at;
off=false;
printf("Set alarm time %d:%d.\n", current_at.h,current_at.m);
break;

case ALARM_EXIT:
exit=true;
break;
default:
printf("Error.Bad command.\n");
}

////// создаем столько нитей, сколько задано пользователем
for (i=1;i<(at.koln+1);i++)
{
//создание очередного потока
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) MyFunc,(LPVOID) i,0,&dwThreadId);
Sleep(50);
printf("kusok vuchislenij ot tekuschej niti=%.15f\n", pr);
// подссумирование кусочка
rez=rez+pr;
printf("Nakaplivaemuj rezultat=%.*f\n", at.toch, rez);
printf("------------------------------------------------------------\n");
//обнуление промежуточного результата
pr=0;
if (hThread == NULL)
{
printf("\nCreateThread #%d failed",i);
return 0;
}
else CloseHandle(hThread);

// проверка, не истекло ои время будильника, не пора ли сварачивать вычисления
GetLocalTime(&st);
if(st.wHour==current_at.h&&st.wMinute==current_at.m)
{

printf("aaaaaaaa!!!!!!!!!!!!!!\n");
// подаем сигнал
Beep( 1750, 1000);
break;
}

}
// проверяем, что шлем клиенту
printf("chto poshlem clientu %.*f\n", at.toch, rez);
otvet.pi=rez;
// ПОКА ТОЛЬКО ПЫТАЕМСЯ ПОСЛАТЬ ответ клиенту
hMail2 = CreateFile(MailSlotPath2,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if (hMail2 == INVALID_HANDLE_VALUE)
{
printf("Error. Can not open mailslot2.\n");
return 1;
}
// ответ точно пишется
WriteFile(hMail2, &otvet, sizeof(PI), &CountBytes2, 0);
////////


} // если нет сообщение в почте
Sleep(20);

}//конец цикла "пока не выход"

}//конец ветки сервера

CloseHandle(hMail);
CloseHandle(hMail2);
return 0;
}[/codebox]




Про оплату... Могу на яндекс-деньги перевести чисто символическую сумму, т.к. студенческая жисть к роскоши не располагает, к сожалению..

Заранее спасибо всем откликнувшимся.
Надеюсь, правила модераторов не нарушила.
 
V

villionk

я конечно это еще не проходил,но у меня вопрос а почему на Си а не на С++ пишешь?C++ Вроде проще и удобней
 
N

Ninoka

Итак курсовик на С++ , суть - распределенное вычисление числа.
Кратко как работает: запускается сервер, потом запускается клиент.
Клиент шлет серверу запрос через ящик, чтобы сервер посчитал ему большое число.
Сервер делает себе нити, каждая из которых считает свой маленький кусочек, потом сервер эти кусочки суммирует.
И вот то что получилось, он должен послать клиенту опять же через маил-слот (но уже другой).

Но! Не шлет!
Что характерно - отправка запроса от клиента серверу - работает нормально.
В чем проблема - не пойму уже неделю.... :)


Вот код (сразу прошу прощение, что много букв):

[codebox]// spo_lab5.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "conio.h"
#include <stdio.h>
#include <windows.h>

const int ALARM_START = 1;
const int ALARM_EXIT = 2;
//структура
struct ALARMTIME
{
int command;
int h;
int m;
int koln;
int toch;

};
struct PI
{
double pi;

};
//глобальная переменная
double pr;
double rez;

//----------------------------------------------------------------------------------------------
double MyFunc (int i)//функция вычисления, используется каждой нитью
{
int j=0;
double a=-3, b=-1;

for (j=0; j<i; j++)
{
a=a+4;
b=b+4;
}
//вычисляем кусочек Пи
pr=1/a-1/b;
printf ("rabota procesa %d, parametru a=%.1f, b=%.1f, rezult pr=%.15f \n\n", i, a, b, pr);
Sleep(20);
return pr;
}
//----------------------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
HANDLE hMail;
HANDLE hMail2;
HANDLE hThread; //описатель созданного потока

int i=0;
char MailSlotName[] = "\\\\.\\mailslot\\SPOMailslot";
char MailSlotName2[] = "\\\\.\\mailslot\\SPOMailslot2";

//структуры
ALARMTIME at;
SYSTEMTIME st;
PI otvet;

DWORD CountBytes, CountBytes2;
DWORD NextSize, NextSize2;
DWORD dwThreadId; //ID созданного потока

char MailSlotPath[] = "\\\\*\\mailslot\\SPOMailslot";
char MailSlotPath2[] = "\\\\*\\mailslot\\SPOMailslot2";
// создаем ящик от лица сервера
hMail=CreateMailslot(MailSlotName,sizeof(ALARMTIME),0,NULL);

if(hMail==INVALID_HANDLE_VALUE)//--------------------ветка клиента---------------------------
{
printf("This is client.\n");


//открываем ящик со стороны клиента
hMail = CreateFile(MailSlotPath,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if (hMail == INVALID_HANDLE_VALUE)
{
printf("Error. Can not open mailslot.\n");
return 1;
}

do // пока не выход гоняем цикл
{
printf("Select command for server:\n1 - start, 2 - close\n");
// ввод юзером параметров
scanf("%d",&at.command);
switch(at.command)
{
case ALARM_START:
printf("Vvedite vremy dly budilnika:\n");
printf("H:");
scanf("%d",&at.h);
printf("M:");
scanf("%d",&at.m);;
printf("Vvedite kolichestvo nitej:");
scanf("%d",&at.koln);;
printf("Vvedite tochnost:");
scanf("%d",&at.toch);;
break;

case ALARM_EXIT:
break;
default:
printf("Error.Bad command.\n");
}
// отправка параметров серверу
WriteFile(hMail, &at, sizeof(ALARMTIME), &CountBytes, 0);

//создание второго ящика для приемки ответа
hMail2=CreateMailslot(MailSlotName2,sizeof(PI),0,NULL);
if(hMail2==INVALID_HANDLE_VALUE)
printf("ne sozdaetsy vtoroj yashcik");

//ПОКА ТОЛЬКО ПОПЫТКА прочитать ответ от сервера
if (!GetMailslotInfo(hMail2, NULL, &NextSize2, NULL, NULL))
{
CloseHandle(hMail2);
printf("Error.Can not get info about mailslot2\n");
getch();
return 1;

}

//сюда не заходит(((
//если есть сообщение в почте
if ((NextSize2 | 0xffff0000) != MAILSLOT_NO_MESSAGE)
{
printf("zashli syda");
if (!ReadFile(hMail2,&otvet, (WORD)NextSize2, &CountBytes2, 0))
{
printf("Error.Can not receive message\n");
CloseHandle(hMail2);
getch();
return 1;
}

printf("pi= %.*f\n", at.toch, otvet.pi);
}
} while (!(at.command==2));

}
else//--------------------ветка сервера---------------------------
{
printf("This is server.\n");
ALARMTIME current_at;
bool off=true;
bool exit=false;
while(!exit)// пока не выход
{
//проверяем состояние ящика
if (!GetMailslotInfo(hMail, NULL, &NextSize, NULL, NULL))
{
CloseHandle(hMail);
printf("Error.Can not get info about mailslot\n");
return 1;
}
//если есть сообщение в почте
if ((NextSize | 0xffff0000) != MAILSLOT_NO_MESSAGE)
{
if (!ReadFile(hMail,&at, (WORD)NextSize, &CountBytes, 0))
{
printf("Error.Can not receive message\n");
CloseHandle(hMail);
return 1;
}

switch(at.command)
{
case ALARM_START:
current_at=at;
off=false;
printf("Set alarm time %d:%d.\n", current_at.h,current_at.m);
break;

case ALARM_EXIT:
exit=true;
break;
default:
printf("Error.Bad command.\n");
}

////// создаем столько нитей, сколько задано пользователем
for (i=1;i<(at.koln+1);i++)
{
//создание очередного потока
hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) MyFunc,(LPVOID) i,0,&dwThreadId);
Sleep(50);
printf("kusok vuchislenij ot tekuschej niti=%.15f\n", pr);
// подссумирование кусочка
rez=rez+pr;
printf("Nakaplivaemuj rezultat=%.*f\n", at.toch, rez);
printf("------------------------------------------------------------\n");
//обнуление промежуточного результата
pr=0;
if (hThread == NULL)
{
printf("\nCreateThread #%d failed",i);
return 0;
}
else CloseHandle(hThread);

// проверка, не истекло ои время будильника, не пора ли сварачивать вычисления
GetLocalTime(&st);
if(st.wHour==current_at.h&&st.wMinute==current_at.m)
{

printf("aaaaaaaa!!!!!!!!!!!!!!\n");
// подаем сигнал
Beep( 1750, 1000);
break;
}

}
// проверяем, что шлем клиенту
printf("chto poshlem clientu %.*f\n", at.toch, rez);
otvet.pi=rez;
// ПОКА ТОЛЬКО ПЫТАЕМСЯ ПОСЛАТЬ ответ клиенту
hMail2 = CreateFile(MailSlotPath2,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);

if (hMail2 == INVALID_HANDLE_VALUE)
{
printf("Error. Can not open mailslot2.\n");
return 1;
}
// ответ точно пишется
WriteFile(hMail2, &otvet, sizeof(PI), &CountBytes2, 0);
////////


} // если нет сообщение в почте
Sleep(20);

}//конец цикла "пока не выход"

}//конец ветки сервера

CloseHandle(hMail);
CloseHandle(hMail2);
return 0;
}[/codebox]




Про оплату... Могу на яндекс-деньги перевести чисто символическую сумму, т.к. студенческая жисть к роскоши не располагает, к сожалению..

Заранее спасибо всем откликнувшимся.
Надеюсь, правила модераторов не нарушила.


Всем спасибо, я разобралась, там просто нужна была банальная синхронизация.
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!