|
Пример программирования протокола IPX в среде
MS Visual C++.
Полный проект можно взять сдесь
#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)
#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;
|