Вот своеобразный пример связи двух сокетов(правда наследованых от CSocket), которые управляются из диалогового окна: Прослушающий сокет, сервер:
| Код | // h-файл class CServerDlg;
class CListenSocket : public CSocket { protected: CServerDlg* pdlg; public: CListenSocket(CServerDlg* m_dlg); virtual ~CListenSocket(); virtual void OnAccept(int nErrorCode);
};
// cpp-файл CListenSocket::CListenSocket(CServerDlg* m_dlg) { pdlg = m_dlg; }
CListenSocket::~CListenSocket() { }
void CListenSocket::OnAccept(int ErrorCode) { if(!pdlg->accept_client()) return; CSocket::OnAccept(ErrorCode); }
|
Клиент:
| Код | //h-файл
# define limiter '#'
class CServerDlg;
class CServerSocket : public CSocket { protected: int index; CServerDlg* pdlg; public: CString knowlege_base_file; CServerSocket(CServerDlg* m_dlg, int ndx); virtual ~CServerSocket(); virtual void OnReceive(int nErrorCode); virtual void OnClose(int nErrorCode); };
// cpp-файл CServerSocket::CServerSocket(CServerDlg* m_dlg, int ndx):index(ndx), pdlg(m_dlg) { }
CServerSocket::~CServerSocket() { }
void CServerSocket::OnReceive(int nErrorCode) {
char buff[4096]; int nRead; nRead = Receive(buff, 4096); if(nRead == SOCKET_ERROR) { AfxMessageBox("ServerSocket :: OnReceive ERROR !!!"); return; } buff[nRead] = '\0'; char msg_type = buff[0]; //отделяю префикс от сообщения CString message = buff; message.Delete(0, 1); switch (msg_type) { case 't': { pdlg->question_selected(index, message); break; } .................................... case 'a': { pdlg->receive_answer(index, message); break; } default: { message=buff; pdlg->default_receive(message); } } CSocket::OnReceive(nErrorCode); }
void CServerSocket::OnClose(int nErrorCode) { pdlg->close_client(index); CSocket::OnClose(nErrorCode); }
|
и функции диалога для работы с сокетами:
| Код | bool CServerDlg::accept_client() { if(!free_socks->not_empty()) { m_list.AddString("Not enougth sockets to connect client"); scroll_list(); return false; } int* index = free_socks->get_head(); s_sock[*index] = new CServerSocket(this, *index); if(l_sock->Accept(*s_sock[*index])) { m_list.AddString("Client Connected - Ok !!!"); ...................................................................... for(CList_templ<askable_atr>::List_node* cur = knowlege_base->get_safe_head(); cur != NULL; cur = cur->next) { st = "l" + cur->inf->description + limiter; sock->Send(st, st.GetLength()); //отправка че-нибудь клиенту } } else { m_list.AddString("Accept - failed !!!"); delete s_sock[*index]; s_sock[*index] = NULL; delete attributes[*index]; attributes[*index] = NULL; } delete index; scroll_list(); return true; }
void CServerDlg::close_client(int index) { s_sock[index]->Close(); delete s_sock[index]; s_sock[index] = NULL; free_socks->add_tail(new int(index)); m_list.AddString("Client disconnected"); }
|
P.S. free_socks - это самописный шаблон списка указателей(в этом примере на сокеты, а не на носки )
P.P.S. чтоб меньше запутывать выбросил куски кода из accept_client, которые не относятся к сокетам.
Добавлено @ 18:45 совсем из головы вылетело - клиент подключается к серверу весьма тривиально:
| Код | if(c_sock->Connect(ip_addr, connect_dlg.m_port)) { //Ok } else { //Fail } здесь ip_addr имеет тип CString, а connect_dlg.m_port - int.
|
|