|
| Скачать фильмы за 20 мин.
| |
Filmplus.Ru - Все новые фильмы за 2008г.
| |

Начни день с нами занеси наш сайт в закладки -)
|
 |
|
|
#include // прототипы функции библиотеки #include // IPX/SPX структуры #include // IPX/SPX структуры и константы для NT платформ
void main () { WSADATA wsaData;
// версия winsock.dll библиотеки WORD wVersionRequested = MAKEWORD( 1, 1 );
// инициализация winsock.dll WSAStartup( wVersionRequested, &wsaData );
// работа с сокетами ……… ………
WSACleanup( ); // не забываем сообщить системе, что мы закончили работу с winsock.dll }
Ну и собственно сокет, тут я дам только кусок отличный от «нормальных» сокетов: WORD SPX_SOCKET = 0x5647
char localNetNum[IPX_NET_SIZE]; char localNodeNum[IPX_NODE_SIZE];
// открытие сокета SOCKET spx_skt = socket (PF_IPX, SOCK_STREAM, NSPROTO_SPX));
// проверим если открылся if (spx ==INVALID_SOCKET) MessageBox (NULL, “Ошибка открытия сокета.”, "Error", MB_OK); // структура для адреса нашего сокета sockaddr_ipx addr_ipx;
/* вот так выглядит структура sockaddr_ipx в WSIPX.H typedef struct sockaddr_ipx { u_short sa_family; u_char sa_netnum[4]; u_char sa_nodenum[6]; unsigned short sa_socket;
} SOCKADDR_IPX, *PSOCKADDR_IPX, FAR *LPSOCKADDR_IPX */
int sz = sizeof (addr_ipx);
// обнулим её memset (&addr_ipx, 0, sz);
addr_ipx.sa_family = AF_IPX; // тип протокола addr_ipx.sa_socket = htons(SPX_SOCKET); // номер сокета
// биндим сокет (привязываем его к номеру сокета) bind(spx_skt, (sockaddr*) &addr_ipx, sz); // узнаем наш адрес getsockname (spx_skt, (sockaddr*) &addr_ipx, &sz);
// наш номер сети memcpy (localNetNum, addr_ipx.sa_netnum, IPX_NET_SIZE); // наш номер узла memcpy (localNodeNum, addr_ipx.sa_nodenum, IPX_NODE_SIZE);В остальном работа с SPX идентична работе TCP сокетов, все выше написанное справедливо и для IPX сокетов, только не забудьте, что последние не могут быть законекчены. Открываются они следующим образом: SOCKET ipx_skt = socket (PF_IPX, SOCK_DGRAM, NSPROTO_IPX);
Передача данных происходит следующим образом:
// структура для хранения удалённого адреса sockaddr_ipx addr_ipx;
// обнуляем её, хотя это не всегда нужно, но и никогда не мешает memset (&addr_ipx, 0, sizeof (addr_ipx));
// тип протокола addr_ipx.sa_family = AF_IPX;
// номер сокета addr_ipx.sa_socket = htons(SOCKET_NR);
// удалённый номер сети memcpy (addr_ipx.sa_netnum, remoteNetNum, IPX_NET_SIZE); // удалённый номер узла memcpy (addr_ipx.sa_nodenum, remoteNodeNum, IPX_NODE_SIZE);
char* buff = “Test string”;
// вот и собственно передача данных sendto (ipx_skt, buff, strlen (buff), 0, (sockaddr*)&addr_ipx, sizeof (addr_ipx));Дальше я дам несколько, на мой взгляд, полезных вещей при работе с данными протоколами. Приём заголовка пакета данныхВ некоторых случаях нам нужен больший контроль над IPX/SPX пакетами и для того чтоб наше приложение могло управлять, изменять заголовок IPX/SPX, нужно вызвать следующий код: // первый вариант нужен wsnwlink.h int rcv_header = 1;
setsockopt (spx_skt, NSPROTO_IPX, IPX_RECVHDR, (char*)&rcv_header, sizeof (rcv_header));
// второй вариант, только для SPX протокола int rcv_header = 1;
setsockopt (spx_skt, NSPROTO_SPX, SPX_RAWSPX, (char*)&rcv_header, sizeof (rcv_header));А вот вам и структура заголовка SPX пакета, взято из WSIPX.H /* WSSpxHeader -- SPX Header structure when in SPXL_SPXRAW mode. */
typedef struct WSSpxHeaderStruc { WSIpxHeader IpxHdr; // 0x00 u_char ConnCtrl; // 0x1E u_char DataStreamType; // 0x1F u_short SrcConnId; // 0x20 u_short DstConnId; // 0x22 u_short SendSeq; // 0x24 u_short AckSeq; // 0x26 u_short AllocNum; // 0x28 } WSSpxHeader, *PWSSpxHeader,FAR *LPWSSpxHeader; // 0x2A (42)В данном режиме Windows Sockets не будут сегментировать пакеты, ограничивая их размер до максимально допустимого протоколом. Широковещательные пакетыШироковещательные пакеты могут быть использованы например в качестве средства «принюхивания» клиента к серверу, это в случае когда мы знаем порт нужного нам сервера, но не знаем его сетевого адреса. sockaddr_ipx addr_ipx;
char* broadcast_msg = “Some broadcast stuff”;
SOCKET ipx_skt = socket (PF_IPX, SOCK_DGRAM, NSPROTO_IPX);
addr_ipx.sa_family = AF_IPX;
// номер сокета, данный номер используется при посылке SAP пакетов в нетваре addr_ipx.sa_socket = htons (0x0452); // = IPXSKT_SAP
// для широковещательных пакетов memset (addr_ipx.sa_netnum, 0, IPX_NET_SIZE); memset (addr_ipx.sa_nodenum, 0xff, IPX_NODE_SIZE);
// устанавливаем флаг для посылки широковещательных пакетов int set_broadcast = 1; setsockopt (ipx_skt, SOL_SOCKET, SO_BROADCAST, (char*)& set_broadcast, sizeof (set_broadcast));
// ну и собственно само вещание sendto (ipx_skt, broadcast_msg, strlen (broadcast_msg), MSG_DONTROUTE, (sockaddr*)&addr_ipx, sizeof (addr_ipx));Установка, изменение DataStreamType в заголовке SPX пакетаЭто в принципе может быть использовано в собственных целях, например для искусственной сегментации своих данных для совместимости разных реализаций протокола. Например, некоторые реализации протокола для ДОС поддерживают максимальную длину пакета в 512 байт, либо принудительно ограниченную сетевыми модулями, вот они и используют DataStreamType, чтобы указать последнюю порцию данных. Устанавливается следующим образом: // Можно использовать любое значение между 0 - 0xfd // следующие значения зарезервированы // #define SPX_HANG_UP 0xFE // #define SPX_HANG_UP_ACK 0xFF int stream_type = 0x05;
setsockopt (spx_skt, NSPROTO_IPX, IPX_DSTYPE, (char*)&stream_type, sizeof(stream_type);Причём данную установку надо делать перед каждым send. Работает всё ОК когда посылаются данные ДОС клиенту, ну а при приеме пакетов WIN клиентом от ДОС клиента DataStreamType не устанавливается, т.е. мы не получим установленное значение DataStreamType ДОС клиентом. Я обошел данную проблему при помощи следующего куска кода: int rcv; // количество принятых байтов за один recv int rcv_total = 0; // общее количество принятых байт
do{ // прием данных rcv = recv (spx_socket, rd_buffer + rcv_total, MAX_BUF_SIZE - rcv_total, 0);
if (rcv > 0) rcv_total += rcv; // если мы что-то получили
}while (rcv > 0); // пока принимаются данныеДанный метод хорош еще тем, что WIN клиент может принять один пакет вместо нескольких посланных ДОС клиентом.
Другие специфические расширения для данных протоколов используемые getsockopt/setsockopt можно найти в файле wsnwlink.h, но (как упоминалось выше) данные расширения для NT платформ могут не работать для других реализаций данных протоколов.
 Автор: admin - 8 ноября 2003 - Комментарии (0)
| | |
|
|
Посетители, находящиеся в группе Гости, не могут оставлять комментарии в данной новости.
| |
Варез портал существует с 2003 - 2007 / Хостинг предоставили MacHoster.Ru
|
|
 |
|
|