ACE_Proactor 를 사용하여 서버를 구성하는데요...서버끼리의 통신을 위해

41 views
Skip to first unread message

miraro

unread,
Feb 20, 2006, 4:17:37 AM2/20/06
to kaug
서버끼리의 통신을 위해 SOKET 을 이용해서
클라이언트를 하나 만들엇는데요..
이놈을 쓰려니 디버그에서는 되는데 릴리지 모드로
들어 가니 ..
TryEnterCriticalSection 여기서 에러가 나서 _WIN32_WINNT=0x0500
을 넣어주니 ..
소켓을 인식 못하네요.. 이거는 어찌 처리를
해야될지...
아니면 다른 방법으로 서버끼리의 통신을 위해서
ACE에서 만들어 줘야 되나요?

redpixel

unread,
Feb 20, 2006, 11:44:46 AM2/20/06
to kaug...@googlegroups.com
TryEnterCriticalSection과 같은 Win32 API를 직접 사용하시지 마시고 ACE_OS namespace에서 한번 찾아보시기 바랍니다. 내부적으로 #define문이 꽤 꼬여있는지라 #include "ace.h" 위에 #include <windows.h> 같은 것을 쓰면 오류가 나는경우가 있습니다. 제가 집이라 정확한 답변을 드리기가 뭣하지만(도움말화일이 회사에 있어서... -_-) ACE에서는 나름대로 wrapping된 동기화 객체들이 꽤 있으니 경우에 맞는것을 사용하는 것이 좋을듯하네요. (크리티컬섹션을 내부적으로 사용하는 동기화객체가 뭣이었는지 기억이 가물.. -_-;;) 내일 회사에 출근하면 답글달아놓도록 하겠습니다.

흐음.. 그리고 서버끼리의 통신이라면 RMCast를 사용해보시기 바랍니다. (물론 아직 개발단계니 실전에 쓰기에는 무리가 있겠죠. 실험해보시는것도.. ^^) 그렇지 않다면 spread나 MMap화일을 통한 공유메모리 트릭기법도 잘 알려져 있는것 같은데요. ^_^ spread는 http://www.spread.org 에서 소스를 받으실수 있습니다.

--
Kwon Tai-in
http://www.redwiki.net
PGPkey: http://www.redwiki.net/pubkey

miraro

unread,
Feb 20, 2006, 8:03:51 PM2/20/06
to kaug
TryEnterCriticalSection 이거는 제가 직접 사용하는게
아니라 ACE 내부에 코드가 있는거라서요..
D:\WORK\ACE\ace/OS.i(2051) : error C2039: 'TryEnterCriticalSection' :
is not a member of '`global namespace''
D:\WORK\ACE\ace/OS.i(2051) : error C2065: 'TryEnterCriticalSection' :
undeclared identifier

이런식으로 에러가 나는거라서요...
_WIN32_WINNT=0x0500 이렇게 세팅부분에 넣어주면 에러가
안나고요...
디버그 모드는 괜찮은데 릴리지 모드에서 에러가
나네요..
그리고 서버끼리의 통신은 서버 머신위치가 틀린
관계로 소켓 통신을 해야됩니다..
서버가 각각 매니지먼트 서버와 로그인서버 등등
여러개로 되어 있어서요...
ace의 편한점은 있는 반면에 좀 까다로운 점이 좀
있군요...

redpixel

unread,
Feb 20, 2006, 8:39:23 PM2/20/06
to kaug...@googlegroups.com
ACE 버전과 어떤 동기화 객체를 사용했는지 알고 싶네요.

miraro

unread,
Feb 20, 2006, 9:34:16 PM2/20/06
to kaug
ACE 버젼은 5.4 버젼이구요
class Acceptor : public ACE_Asynch_Acceptor<Receiver>
class Receiver : public ACE_Service_Handler

이 객체를 사용하여서요....

class Receiver;

class Acceptor : public ACE_Asynch_Acceptor<Receiver>
{
friend class Receiver;
public:
int get_number_sessions (void) { return this->sessions_; }
size_t get_total_snd (void) { return this->total_snd_; }
size_t get_total_rcv (void) { return this->total_rcv_; }
long get_total_w (void) { return this->total_w_; }
long get_total_r (void) { return this->total_r_; }

Acceptor (void);
virtual ~Acceptor (void);

void stop (void);
void cancel_all (void);

// Virtual from ACE_Asynch_Acceptor
Receiver *make_handler (void);

private:
void on_new_receiver (Receiver &rcvr);
void on_delete_receiver (Receiver &rcvr);

ACE_SYNCH_RECURSIVE_MUTEX lock_;
int sessions_;
Receiver *list_receivers_[MAX_RECEIVERS];
size_t total_snd_;
size_t total_rcv_;
long total_w_;
long total_r_;
};


class Receiver : public ACE_Service_Handler
{
friend class Acceptor;
public:
Receiver (Acceptor *acceptor = 0, int index = -1);
~Receiver (void);

size_t get_total_snd (void) { return this->total_snd_; }
size_t get_total_rcv (void) { return this->total_rcv_; }
long get_total_w (void) { return this->total_w_; }
long get_total_r (void) { return this->total_r_; }

// This is called to pass the new connection's addresses.
virtual void addresses (const ACE_INET_Addr& peer,
const ACE_INET_Addr& local);

/// This is called after the new connection has been accepted.
virtual void open (ACE_HANDLE handle,
ACE_Message_Block &message_block);

virtual int close();
virtual int send_packet(const void* buf, size_t size);

User * user_;
protected:
/**
* @name AIO callback handling
*
* These methods are called by the framework
*/
/// This is called when asynchronous <read> operation from the
/// socket completes.
virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result
&result);

/// This is called when an asynchronous <write> to the socket
/// completes.
virtual void handle_write_stream (const
ACE_Asynch_Write_Stream::Result &result);
virtual int recv_packet(ACE_Message_Block *&_message);

virtual int process_packet(ACE_Message_Block *packet);
virtual void on_close();
private:
int initiate_read_stream (void);
int initiate_write_stream (ACE_Message_Block &mb, size_t nbytes);
void cancel ();

Acceptor *acceptor_;
int index_;

ACE_Asynch_Read_Stream rs_;
ACE_Asynch_Write_Stream ws_;
ACE_HANDLE handle_;
ACE_Message_Block* msg_frag_;
char szMsgremain[4096*2];
int m_nRemaincount;
ACE_SYNCH_MUTEX lock_;

long io_count_; // Number of currently outstanding I/O
requests
int flg_cancel_;
size_t total_snd_; // Number of bytes successfully sent
size_t total_rcv_; // Number of bytes successfully received
long total_w_; // Number of write operations
long total_r_; // Number of read operations
};
void init (port)
{
ACE_INET_Addr addr(port);
if (myTask_.start (6, proactor_type, 512) == 0) {
acceptor_.open(addr,0);
//connector_.open(addr);
//myTask_.open ();
ACE_Time_Value inital(0);
ACE_Time_Value interval(10);
ACE_Proactor::instance()->schedule_timer(timer_,0,inital,interval);
}


}

뭐 이런식으로 구현을 했고요...

miraro

unread,
Feb 20, 2006, 11:45:10 PM2/20/06
to kaug
에구 그냥 ACE_SOCK_Connector 와 ACE_SOCK_Stream 으로 통신
프로그램을 만들어서 해결햇네요 클라이언트는요..

그런데 아직도 왜 디버그는


D:\WORK\ACE\ace/OS.i(2051) : error C2039: 'TryEnterCriticalSection' :
is not a member of '`global namespace''
D:\WORK\ACE\ace/OS.i(2051) : error C2065: 'TryEnterCriticalSection' :
undeclared identifier

에러가 안나고 릴리즈는 나는지 모르겟네요...

Reply all
Reply to author
Forward
0 new messages