15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Пример программирования протокола IPX в среде MS Visual C++.

Полный проект можно взять сдесь

  Листинг 1 (Mainw.cpp)

#include "class.h"


/*
char buf[10];
sprintf(buf,"%d",);
MessageBox(buf,"Проверка",MB_OK );
*/

///////////////////////////////////////////////////////////////
//Функция создания окна
///////////////////////////////////////////////////////////////

CMainWnd::CMainWnd(LPCSTR Class)
{

Create(Class,"Socket",WS_OVERLAPPEDWINDOW| WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX,rectDefault,NULL,"TIMERMENU");
//WS_SYSMENU|WS_MAXIMIZEBOX|WS_MINIMIZEBOX,size,NULL,"TIMERMENU");

}


BOOL CApp::InitInstance()
{
CBrush r;

r.CreateStockObject(WHITE_BRUSH);
LPCSTR cname=AfxRegisterWndClass(0,NULL,r,LoadIcon("MAIN"));

m_pMainWnd=new CMainWnd(cname);
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();


return TRUE;
}


/////////////////////////////////////////////////////////////////////////////////////////////
//Обработка сообщения от Главного окна
/////////////////////////////////////////////////////////////////////////////////////////////


afx_msg void CMainWnd::OnPaint()
{

CPaintDC DC(this);

}

afx_msg void CMainWnd::OnButton()
{

//Заполняем буфер который передаем
RcBuffer[1] = 0x50;
RcBuffer[2] = 0xC0;
RcBuffer[3] = 0x10;
RcBuffer[4] = 0xC0;
//Передача
SendDGRM(sock,IPX_RECV,BROADCAST_NODE,RcBuffer,5);

if(snd==SOCKET_ERROR){MessageBox("Ошибка","Проверка",MB_OK );}
}


afx_msg void CMainWnd::OnClose()
{

PostQuitMessage(0);
}

afx_msg int CMainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{

    bsend.Create("Передать",BS_TEXT|WS_TABSTOP,CRect(30,10,200,50),this,ID_BUTTON);
bsend.ShowWindow(SW_SHOW);

    wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup(wVersionRequested, &wsaData );
if ( err != 0 )
    {
printf("No winsock.dll\n");
MessageBox("No winsock.dll","lejnsdlj",MB_OK);
    }
        //Создаем сокет1 для пердачи
    if((sock=CreateDGRMSocket(IPX_SEND))==0)
    {
MessageBox("Ошибка инициализации сокета датаграмм","Ошибка драйвера",MB_ICONSTOP);
//return FALSE;
    }
    //Создаем сокет2 для приема
    if((sock1=CreateDGRMSocket(IPX_RECV))==0)
    {
MessageBox("Ошибка инициализации сокета датаграмм","Ошибка драйвера",MB_ICONSTOP);
//return FALSE;
    }
    //Создаем сообщение которое возникает при принятии сообщения
    if(!AsyncSel(sock1,"Ошибка установки события FD_READ и сообщения MW_READ",wMsg1,FD_READ))
return 0;
return 0;


}


/////////////////////////////////////////////////////////////////////////////////////////////
//Обработка сообщения от меню
/////////////////////////////////////////////////////////////////////////////////////////////
   
afx_msg void CMainWnd::OnExit()
{
SendMessage(WM_CLOSE);
closesocket(sock);
}

afx_msg void CMainWnd::OnAbout()
{
//CenterWindow(this);
AboutDialog about("ABOUT",this);
about.DoModal();
}


afx_msg LRESULT CMainWnd::OnRecv(WPARAM wParam,LPARAM lParam)
{
int Len=0;

sRecAddr = sizeof(struct sockaddr);
memset(RcBuffer,0,sizeof(RcBuffer));
//Прием данных
Len = recvfrom(sock1,(char*)RcBuffer,sizeof(RcBuffer),0,&RecAddr,&sRecAddr);
//Запоминаем адрес в более удобном виде
memcpy(&Ipx_Addr,&RecAddr,sizeof(SOCKADDR_IPX));

MessageBox("Получил","Проверка",MB_OK );
return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////



SOCKET CMainWnd::CreateDGRMSocket(BYTE* IdSock)
{
SOCKET        sock;
SOCKADDR_IPX addr;
PSOCKADDR_IPX pSockAddr;

//Получаем сокет
//IPX семейство,послед.передача,протокол SPX
sock = socket(AF_IPX,SOCK_DGRAM,NSPROTO_IPX);
if(sock==INVALID_SOCKET)
    {
    MessageBox("Ошибка получения сокета","Ошибка",MB_OK|MB_ICONSTOP);
    return 0;
    }//if(sock==INVALID_SOCKET)

//Сокет является широковещательным
Enable_Broadcasts(sock,TRUE);

//Готовим связку сокета с номером и сетевым адресом
memset(&addr, 0, sizeof(addr)); // Очищаем память
pSockAddr = (PSOCKADDR_IPX)&addr; // Set pointer
pSockAddr->sa_family = AF_IPX;        // IPX Family
// Записываем номер передающего сокета
memcpy(&pSockAddr->sa_socket,IdSock, 2);

//Получаем связанный сокет с локальным адресом
if(bind(sock,(PSOCKADDR)pSockAddr,sizeof(SOCKADDR_IPX)) == SOCKET_ERROR)
{
MessageBox("Не могу связать сокет с локальным адресом",
                    "Ошибка сокета",MB_OK|MB_ICONSTOP);

}//if (bind(sock,(PSOCKADDR)pSockAddr,sizeof(SOCKADDR_IPX)) == SOCKET_ERROR)

//Делаем сокет широковещательным
//Это необходимо сделать иначе мы не услышим что делается в сети
Enable_Broadcasts(sock,TRUE);

return sock;
}//SOCKET CreateDGRMSocket(HWND,BYTE*);

BOOL CMainWnd::AsyncSel(SOCKET s,char *Text,UINT msg,long Event)
{
//Указываем окно в которое будут поступать сообщения которые тоже указываем
if(WSAAsyncSelect(s,m_hWnd,msg,Event))
{
    MessageBox(Text,"Ошибка",MB_OK|MB_ICONSTOP);
    closesocket(s);
    return 0;
}
return TRUE;
}//BOOL AsyncSel(HWND hwnd,HWND hwndParent,SOCKET s,char *Text,UINT msg,long Event)


int CMainWnd::Enable_Broadcasts(SOCKET s,BOOL EnableBrCst)
{
int rc;
BOOL optval = EnableBrCst;

    rc = setsockopt(s, SOL_SOCKET, SO_BROADCAST, (const char FAR*)&optval, sizeof(BOOL));

if (rc == SOCKET_ERROR) {
        MessageBox("Не могу сделать широковещательный сокет",
                    "Ошибка сокета",MB_OK|MB_ICONSTOP);
closesocket(s);
return 1;
}
return 0;
}


BOOL CMainWnd::SendDGRM(SOCKET sock,BYTE *toSock,BYTE *toNodeAdrr,
            BYTE *Message,int Len2)
{
SOCKADDR_IPX addr;
int            Len1;    

//Канал занят
//if(DGRMSocketBusy) return FALSE;

//DGRMSocketBusy = TRUE;
//Готовим адрес
memset(&addr, 0, sizeof(addr)); // Очищаем память
addr.sa_family = AF_IPX; // IPX Family
// Записываем номер принимающего сокета
memcpy(&addr.sa_socket,toSock,2);
// Записываем номер принимающего узла
memcpy(&addr.sa_nodenum,toNodeAdrr,6);

//Отправляем пакет по узлу
if((Len1=sendto(sock,(const char*)Message,Len2,0,(const struct sockaddr *)&addr,16))!=Len2)
{
    Len2 = WSAGetLastError();
    if(SOCKET_ERROR==Len1)
        MessageBox("Не могу отправить пакет узлу сети",
                    "Сетевая ошибка",MB_OK|MB_ICONSTOP);
else
        MessageBox("Пакет не принят",
                    "Сетевая ошибка",MB_OK|MB_ICONSTOP);
return 0;
}//if()
return TRUE;
}//BOOL SendDGRM(HWND hwnd,SOCKET sock,BYTE *toSock,BYTE *toNodeAdrr,
//            BYTE *Message,int Len2)


  Листинг 2 (Class.h)

#include <afxwin.h>
#include <winsock.h>
#include <wsipx.h>

char buf[80];//общий буфер

//Элементы меню
#define ID_EXIT 102//Выход
#define ID_HELP1 103//Помощь
#define ID_ABOUT 104//О программе

int wMsg1=WM_USER+1;


#define ID_BUTTON 1000// кнопка в нлавном окне Передать

#define SIZE_BUFFER_IO 2


int snd, err;
WORD wVersionRequested;
WSADATA wsaData;
SOCKET sock,sock1;
BYTE BROADCAST_NODE[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//Broadcast сокет
BYTE IPX_SEND[2] = {0xcf,0xfc};//Сокет
BYTE IPX_RECV[2] = {0x2f,0xfc};//Сокет
BYTE RcBuffer[SIZE_BUFFER_IO*800];//~204kB        //Буффер приема

static struct sockaddr RecAddr;
static int    sRecAddr;


//класс главного окна
class CMainWnd:public CFrameWnd
{


public:

SOCKET CreateDGRMSocket(BYTE* );
int Enable_Broadcasts(SOCKET ,BOOL );
BOOL SendDGRM(SOCKET,BYTE *,BYTE *,BYTE *,int );
BOOL AsyncSel(SOCKET,char *,UINT ,long );
SOCKADDR_IPX Ipx_Addr;
CButton bsend;

CMainWnd(LPCSTR Class);
afx_msg void OnDestroy();
afx_msg void OnPaint();
afx_msg void OnClose();
afx_msg void OnExit();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnButton();
afx_msg LRESULT OnRecv(WPARAM wParam,LPARAM lParam);
afx_msg void OnAbout();

DECLARE_MESSAGE_MAP()

};

//класс всего приложения
class CApp:public CWinApp
{
public:
BOOL InitInstance();
};

//класс диалога About
class AboutDialog:public CDialog
{

public:
AboutDialog(char *DialogName, CWnd *Ower):
CDialog(DialogName,Ower){}
DECLARE_MESSAGE_MAP()
};


//Очередь сообщения Диалога About
BEGIN_MESSAGE_MAP(AboutDialog,CDialog)
END_MESSAGE_MAP()


//Очередь сообщения главного окна
BEGIN_MESSAGE_MAP(CMainWnd,CFrameWnd)
ON_WM_PAINT()
ON_WM_CREATE()
ON_COMMAND(ID_EXIT,OnExit)
ON_COMMAND(ID_ABOUT,OnAbout)
ON_COMMAND(ID_BUTTON,OnButton)
ON_MESSAGE(wMsg1,OnRecv)
ON_COMMAND(ID_EXIT,OnExit)
END_MESSAGE_MAP()

CApp CApp;