Corba

  • Автор темы Ellmi
  • Дата начала
E

Ellmi

Гость
#1
Доброго времени суток!
Создаю клиент-серверное приложение, используя CORBA.
Необходимо реализовать работу нескольких клиентских приложений (копий одного приложения) с одним серверным. Взаимодействие одного клиента с сервером получается, а 2х клиентов с одним сервером - нет, либо серверное приложение закрывается при запуске 2го клиента, либо запускается 2я копия сервера .. подскажите как исправить, в чем тут дело, и возможна ли вообще работа нескольких клиентов одновременно?

допустим у сервера одна функция

MyServer.idl
Код:
module Server{ 
interface MyServer{	
long Entrance(in string UserName);	};};
Описание этой функции сервера
Код:
#pragma hdrstop
#include <vcl.h>
#include <corba.h>
#include <string.h>
#include "MyServerServer.h"
#include "Unit1.h" 
//--------------------------------------------------------------------------- 
#pragma package(smart_init)
extern TForm1 *Form1;
TStringList *Users = new TStringList; 

MyServerImpl::MyServerImpl(const char *object_name):		_sk_Server::_sk_MyServer(object_name)				 {								  } 

CORBA::Long MyServerImpl::Entrance(const char* _UserName)
{
AnsiString user_name(_UserName);
for(int i=0; Users->Count; i++)
{
//если пользователь с этим именем уже он-лайн
if (Users->Strings[i]==user_name)
{
return 0;
}
}
Form1->Memo1->Lines->Add(user_name + " подключился к серверу");
Users->Add(user_name);
return 1;
}
Клиентское приложение, в котором эта функция вызывается

Unit1.срр
Код:
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
AnsiString UserName;

Server::MyServer_ptr __fastcall TForm1::GetS(void){
if (FS == NULL)
{
FS = Server::MyServer::_bind("MyServerObject");
}
return FS;
}

void __fastcall TForm1::SetS(Server::MyServer_ptr _ptr)
{
FS = _ptr;
}

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{}
//---------------------------------------------------------------------------


void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (Edit1->Text == "")
{MessageBox(NULL,"Не введено имя пользователя!","Ошибка", MB_OK);}
else
{
UserName = Edit1->Text;
if (S->Entrance(UserName.c_str()) == 1)
{
Caption = Caption + " - " + UserName;
}
else {MessageBox(NULL,"Пользователь с этим именем уже в системе","Ошибка", MB_OK);}
}
}
Unit1.h
Код:
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Grids.hpp>
#include <Menus.hpp>
#include "..\Server\MyServer_c.hh"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE-managed Components
TButton *Button1;
TEdit *Edit1;
TLabel *Label1;
void __fastcall Button1Click(TObject *Sender);

private:	// User declarations
Server::MyServer_ptr __fastcall GetS();
Server::MyServer_var FS;
void __fastcall SetS(Server::MyServer_ptr _ptr); 
public:		// User declarations
__property Server::MyServer_ptr S = {read = GetS, write = SetS};
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Подскажите пожалуйста что не так?
 
E

Ellmi

Гость
#2
Сейчас, попробовала запустить, серверное приложение, потом 1го клиента, и он ввел какое-то имя, потом запустила опять же клиентское и ввела тоже самое имя, получила ответ "Пользователь с этим именем уже в системе", значит с сервером клиенты взаимодействуют нормально!)).. но если ввести другой имя на 2м клиенте, то сервер закрывается, а потом еще появляется сообщение об ошибке "External exception EEFFACE". Как этого избежать?
 
D

dreamer

Гость
#3
У Вас случайно нет при компиляции каких-нибудь warning'ов на строке:
for(int i=0; Users->Count; i++)
Ибо условие, видимо, не дописано. При отсутствии залогиненных пользователей ноль в Count интерпретируется как false и осуществляется выход из цикла. Если логинится уже залогиненный пользователь, выход из цикла осуществляется на "return 0". В третьем случае Users->Count будет > 0, что будет интерпретироваться как true и цикл будет бесконечным, а на Users->Strings, разумеется, будет ошибка доступа к памяти.
 
E

Ellmi

Гость
#4
dreamer, спасибо!)).. это я правда уже заметила.. у меня часто такое случается :( .. при этом ни разу не было warning'ов.. уже при запуске сервера из среды стало ясно "exeption class EStringListError with message 'List index out of bounds (1)'"
сервер почему-то с 1го раза в среде не запускается : Project raised exeption class PortableServer_POA::AdapterNonExisten with message 'Exeption Object Adress:0xDFC4B2'
Если нажать на OK, и еще 2 раза запустить, то запускается =), так и не получалось сначала увидеть в чем дело =(
Интересно почему так с запуском