После
добавления нового имени этому имени присваивается так называемый номер имени
(name number), который используется для передачи данных по сети.
Сравнивая
методы адресации, используемые протоколами IPX/SPX и NETBIOS, нетрудно
заметить, что метод адресации протокола NETBIOS более удобен. Вы можете
адресовать данные не только одной станции (как в IPX и SPX) или всем станциям
сразу (как в IPX), но и группам станций, имеющим одинаковое групповое имя. Это
может быть удобно, если в сети работают несколько групп пользователей, которые
интенсивно обмениваются данными между собой.
Другим
преимуществом схемы адресации протокола NETBIOS перед схемой адресации
протоколов IPX/SPX можно считать отсутствие необходимости получать в фирме
Novell свой собственный номер сокета для идентификации вашего программного
обеспечения. Вы можете придумать свое собственное уникальное групповое имя,
включающее, например, название программы и вашей фирмы, и использовать его для
работы по схеме клиент-сервер.
Канал Mailslot создается серверным
процессом с помощью специально предназначенной для этого функции CreateMailslot. После создания серверный процесс
получает идентификатор канала Mailslot.
Пользуясь этим идентификатором, сервер может читать сообщения, посылаемые в
канал клиентскими процессами. Однако сервер не может выполнять над каналом Mailslot операцию записи, так как этот канал
предназначен только для односторонней передачи данных - от клиента к серверу.
При ошибке функцией CreateMailslot возвращается значение
INVALID_HANDLE_VALUE. Код ошибки можно определить
при помощи функции GetLastError.
Прежде чем приступить к работе с
каналом Mailslot, клиентский процесс должен
его открыть. Для выполнения этой операции следует использовать функцию
CreateFile. Запись сообщений в канал Mailslot выполняет клиентский
процесс, вызывая для этого функцию WriteFile.
Серверный процесс может читать
сообщения из созданного им канала Mailslot при помощи функции ReadFile.
Заметим, что перед выполнением операции чтения следует проверить состояние
канала Mailslot. Если в нем нет сообщений,
то функцию ReadFile вызывать не следует. Для
проверки состояния канала вы должны воспользоваться функцией GetMailslotInfo. С помощью функции
SetMailslotInfo серверный процесс может
изменить время ожидания для канала Mailslot уже после его создания.
Исходники
Main.cpp
#include <vcl.h>
#include <stdlib.h>
#include <StrUtils.hpp>
#pragma hdrstop
#include "Main.h"
#include "Podkluch.h"
#include "GameParam.h"
#include "About.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link
"LMDCustomBevelPanel"
#pragma link
"LMDCustomControl"
#pragma link
"LMDCustomPanel"
#pragma link
"LMDSimplePanel"
#pragma link "LMDBackPanel"
#pragma link
"LMDCustomParentPanel"
#pragma link
"LMDBaseControl"
#pragma link
"LMDBaseGraphicControl"
#pragma link "LMDBaseLabel"
#pragma link "LMDControl"
#pragma link
"LMDCustomSimpleLabel"
#pragma link
"LMDSimpleLabel"
#pragma link "lmdcont"
#pragma link
"LMDCustomComponent"
#pragma link
"LMDCustomStatusBar"
#pragma link "LMDStatusBar"
#pragma link
"LMDCustomPanelFill"
#pragma link "LMDPanelFill"
#pragma link
"LMDCustomScrollBox"
#pragma link "LMDListBox"
#pragma link
"LMDCustomFormFill"
#pragma link "LMDFormFill"
#pragma link
"LMDWndProcComponent"
#pragma link "LMDBaseShape"
#pragma link
"LMDShapeControl"
#pragma link
"LMDCustomLabel"
#pragma link "LMDDrawEdge"
#pragma link "LMDLabel"
#pragma link "LMDBaseImage"
#pragma link
"LMDCustomGroupBox"
#pragma link
"LMDCustomLImage"
#pragma link
"LMDGraphicControl"
#pragma link "LMDGroupBox"
#pragma link "LMDLImage"
#pragma link
"LMDBaseGraphicButton"
#pragma link
"LMDCustomShapeButton"
#pragma link "LMDShapeButton"
#pragma resource "*.dfm"
TMainForm *MainForm;
extern bool IsServer;
extern AnsiString Protocoli[];
extern int KolKub;
extern int MaxOch;
extern int choosenProt;
extern AnsiString ServerHostName;
extern AnsiString ServerHostIP;
extern bool IsHostName;
extern bool IsIgrayut;
extern int NomHoda;
extern int MyCurOch;
extern int MyWholeOch;
extern int HisWholeOch;
extern bool IsYaFixed;
extern bool IsHeFixed;
extern int HisWinPoPartiam;
extern int MyWinPoPartiam;
extern int NomPartia;
int *MasPriem;
//---------------------------------------------------------------------------
__fastcall
TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall
TMainForm::FormCreate(TObject *Sender)
{
FirstTimeShow=true;
IsVisitApplicationBox=false;
}
//---------------------------------------------------------------------------
void __fastcall
TMainForm::FormActivate(TObject *Sender)
{
if(FirstTimeShow)
{
FirstTimeShow=false;
InterfaceBezIgri();
menuBeginClick(this);
}
}
//---------------------------------------------------------------------------
void __fastcall
TMainForm::menuBeginClick(TObject *Sender)
{
if (IsIgrayut)
{
menuStopClick(this);
if (IsIgrayut) return;
}
if (UstanParametrov())
//вызов 2-х форм для установки параметров
{
//----подключение----
switch(choosenProt)
{
case 0:
IPXConnect();
break;
case 1:
TCPIPConnect();
break;
case 2:
NetBiosConnect();
break;
case 3:
MailSlotConnect();
break;
case 4:
PipeConnect();
break;
}
if(IsServer)
lbStat->Caption="Ожидается соединение
с клиентом...";
}
}
//---------------------------------------------------------------------------
bool __fastcall
TMainForm::UstanParametrov(void)
{
int md1,md2;
for(;;)
{
md1=FormParamConnect->ShowModal();
FormParamConnect->Close();
if (md1==mrOk)
{
if (IsServer)
{
md2=FormGameParam->ShowModal();
if (md2==mrOk) return
1;
else continue;
}
else return 1;
}
else return 0;
}
}
void __fastcall TMainForm::OtobrazhDannihSopernika(int
*MasPriem)
{
Graphics::TBitmap *Bitmap2 = new
Graphics::TBitmap();
AnsiString strCat;
if(IsServer)
{
strCat="_2";
}
else
{
strCat="";
}
if(KolKub==1)
{
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[3])+strCat);
Kubiki2[0]->Picture->Bitmap=Bitmap2;
Kubiki2[0]->Left=MasPriem[4];
Kubiki2[0]->Top=MasPriem[5];
Kubiki2[0]->Visible=true;
}
else if (KolKub==2)
{
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[3])+strCat);
Kubiki2[0]->Picture->Bitmap=Bitmap2;
Kubiki2[0]->Left=MasPriem[4];
Kubiki2[0]->Top=MasPriem[5];
Kubiki2[0]->Visible=true;
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[6])+strCat);
Kubiki2[1]->Picture->Bitmap=Bitmap2;
Kubiki2[1]->Left=MasPriem[7];
Kubiki2[1]->Top=MasPriem[8];
Kubiki2[1]->Visible=true;
}
else if (KolKub==3)
{
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[3])+strCat);
Kubiki2[0]->Picture->Bitmap=Bitmap2;
Kubiki2[0]->Left=MasPriem[4];
Kubiki2[0]->Top=MasPriem[5];
Kubiki2[0]->Visible=true;
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[6])+strCat);
Kubiki2[1]->Picture->Bitmap=Bitmap2;
Kubiki2[1]->Left=MasPriem[7];
Kubiki2[1]->Top=MasPriem[8];
Kubiki2[1]->Visible=true;
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[9])+strCat);
Kubiki2[2]->Picture->Bitmap=Bitmap2;
Kubiki2[2]->Left=MasPriem[10];
Kubiki2[2]->Top=MasPriem[11];
Kubiki2[2]->Visible=true;
}
else
{
Bitmap2->LoadFromResourceName((unsigned int)HInstance,"KUB"+IntToStr(MasPriem[3])+strCat);
Kubiki2[0]->Picture->Bitmap=Bitmap2;
Kubiki2[0]->Left=MasPriem[4];
Kubiki2[0]->Top=MasPriem[5];
Kubiki2[0]->Visible=true;
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[6])+strCat);
Kubiki2[1]->Picture->Bitmap=Bitmap2;
Kubiki2[1]->Left=MasPriem[7];
Kubiki2[1]->Top=MasPriem[8];
Kubiki2[1]->Visible=true;
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[9])+strCat);
Kubiki2[2]->Picture->Bitmap=Bitmap2;
Kubiki2[2]->Left=MasPriem[10];
Kubiki2[2]->Top=MasPriem[11];
Kubiki2[2]->Visible=true;
Bitmap2->LoadFromResourceName((unsigned
int)HInstance,"KUB"+IntToStr(MasPriem[12])+strCat);
Kubiki2[3]->Picture->Bitmap=Bitmap2;
Kubiki2[3]->Left=MasPriem[13];
Kubiki2[3]->Top=MasPriem[14];
Kubiki2[3]->Visible=true;
}
HisWholeOch=MasPriem[2];
lbHisWholeOch->Caption=IntToStr(MasPriem[2]);
delete Bitmap2;
}
//-----------пришли данные
соперника--------------------------------------------
void __fastcall TMainForm::Priem(int
*MasPriem)
{
if(MasPriem[0]==0) //первый ответ
сервера клиенту
{
AnsiString mess;
mess="Ваш соперник
выбрал следующие параметры игры:\nКоличество кубиков:
"+IntToStr(MasPriem[1])+"\nМаксимальное количество очков:
"+IntToStr(MasPriem[2]);
IsVisitApplicationBox=true;
Application->MessageBoxA(mess.c_str(),"Параметры игры",MB_OK);
KolKub=MasPriem[1];
MaxOch=MasPriem[2];
InterfaceBeginNewGame();
ChangeInterfacePerehodHoda(0);
IsVisitApplicationBox=false;
}
else if (MasPriem[0]==1) //соперник бросил
{
shapeBrosil->Brush->Color=0x0000CE00;
OtobrazhDannihSopernika(MasPriem);
if(!IsServer)
{
NomHoda++;
}
enum TypeDannihForTabl
DannieForTabl;
DannieForTabl=hebrosil;
ZapolnTabl(DannieForTabl);
if(IsYaFixed &&
HisWholeOch>MyWholeOch && HisWholeOch<=MaxOch)
{
ViProigrali();
}
else if (HisWholeOch>MaxOch)
{
lbHisWholeOch->Font->Color=clRed;
ViViigrali();
}
else if(IsYaFixed &&
HisWholeOch<=MyWholeOch)
{
ChangeInterfacePerehodHoda(0);
}
else
{
ChangeInterfacePerehodHoda(1);
}
}
else if (MasPriem[0]==2) //соперник зафиксировал
{
IsHeFixed=true;
lbHisWholeOch->Font->Color=clRed;
shapeFixed->Brush->Color=0x000000CE;
if(!IsServer)
{
NomHoda++;
}
enum TypeDannihForTabl
DannieForTabl;
DannieForTabl=hefixed;
ZapolnTabl(DannieForTabl);
if(IsYaFixed &&
MyWholeOch==HisWholeOch)
{
Nichia();
}
else
if(MyWholeOch>HisWholeOch)
{
ViViigrali();
}
else
{
ChangeInterfacePerehodHoda(1);
}
}
else if (MasPriem[0]==3) //соперник разорвал соединение
{
IsVisitApplicationBox=true;
Application->MessageBoxA("Ваш соперник разорвал соединение.\nИгра окончена.","Разрыв соединения",MB_OK);
switch(choosenProt)
{
case 0:
IPXCloseConnection();
break;
case 1:
TCPIPCloseConnection();
break;
case 2:
NetBiosCloseConnection();
break;
case 3:
MailSlotCloseConnection();
break;
case 4:
PipeCloseConnection();
break;
}
for (int i=0;i<KolKub;i++)
{
delete Kubiki1[i];
delete Kubiki2[i];
}
IsIgrayut=false;
InterfaceBezIgri();
IsVisitApplicationBox=false;
}
delete [] MasPriem;
}
//----------------процедура
заполнения таблицы----------------------------------
void __fastcall
TMainForm::ZapolnTabl(enum TypeDannihForTabl DannieForTabl)
{
if(IsServer)
{
if(DannieForTabl==yabrosil)
{
listboxOchki->Items->Add("
"+IntToStr(NomHoda)+"; "+IntToStr(MyCurOch));
listboxOchki->TopIndex=NomHoda-1;
if(NomHoda==9)
{
listboxOchki->Width=236;
listboxOchki->Left=14;
}
}
else if (DannieForTabl==yafixed)
{
listboxOchki->Items->Add("
"+IntToStr(NomHoda)+"; 0");
listboxOchki->TopIndex=NomHoda-1;
if(NomHoda==9)
{
listboxOchki->Width=236;
listboxOchki->Left=14;
}
}
else if
(DannieForTabl==hebrosil)
{
listboxOchki->SetItemPart(NomHoda-1,2,"
"+IntToStr(MasPriem[1]));
listboxOchki->TopIndex=NomHoda-1;
}
else
{
listboxOchki->SetItemPart(NomHoda-1,2," 0");
listboxOchki->TopIndex=NomHoda-1;
}
}
else
{
if(DannieForTabl==yabrosil)
{
listboxOchki->SetItemPart(NomHoda-1,1," "+IntToStr(MyCurOch));
listboxOchki->TopIndex=NomHoda-1;
}
else if (DannieForTabl==yafixed)
{
listboxOchki->SetItemPart(NomHoda-1,1," 0");
listboxOchki->TopIndex=NomHoda-1;
}
else if
(DannieForTabl==hebrosil)
{
listboxOchki->Items->Add(" "+
IntToStr(NomHoda)+";; "+IntToStr(MasPriem[1]));
listboxOchki->TopIndex=NomHoda-1;
if(NomHoda==9)
{
listboxOchki->Width=236;
listboxOchki->Left=14;
}
}
else
{
listboxOchki->Items->Add(" "+
IntToStr(NomHoda)+";; 0");
listboxOchki->TopIndex=NomHoda-1;
if(NomHoda==9)
{
Страницы: 1, 2, 3, 4
|