IPX (Internetwork Packet Exchange), SPX (Sequenced Packet Exchange)

Comunicaciones. Transmisión de Datos. Socket. WinSock. Dashed. {LAN}. Enrutado. Routable

2 downloads 286 Views 30KB Size

Recommend Stories


Me Duele Review Packet
Nombre: __________________ Fecha: __________________ Me Duele Review Packet This review document is broken into five main sections: PAGE SECTION D

Customer Welcome Packet
Customer Welcome Packet Contenido Nuestras Oficinas ................................................................................................

Customer Documentation Packet
DocuColor 7000AP/8000AP Customer Documentation Packet 701P47619 Customer Documentation Packet Documentation client Pacchetto della documentazione per

Espanol. Informal Command. Packet #9
Nombre: Fecha: el de Espanol Informal Command Packet #9 • • % Senora Lambot Senorita Carlow LOS MANDATOS INFORMALES Informal commands are the typ

Espaool Los deporte Packet # 10
Nombre: Fecha: el de Espaool Los deporte Packet # 10 Senora Lambot Senorlta Carlow / Me llamo Fecha Los Deportes - Sports Los deportes Sports 1

Story Transcript

Taller Numero 1 Comunicación de Datos Indice. 1. Introducción 3 2. Apreciación global de IPX/SPX 3 2.1. La Familia de Direcciones AF_IPX 3 2.2. Familia de Identificadores de Protocolo de IPX 4 2.3. Transmisión a Red Local. 4 2.4. Transmisión a todas las rutas. 4 2.5. Transmisión Dirigida. 4 2.6. Algo sobre el Tamaño de Paquete de comunicación. 4 3. Cable coaxial 6 4. Códigos de los programas de Comunicación: 7 Funciones de Winsock 7 Código del programa en Visual Basic 12 Código del programa en C ++ Builder 14 Código del programa en Delphi 18 5. Conclusiones: 21 6. Bibliografía 21 1.Introducción sobre IPX/SPX Este informe cubre una extensión a WinSock 2 eso es específico a la familia IPX de protocolos de transporte. También describe aspectos de WinSock bajo 2 funciones que requieren consideración especial o qué puede exhibir única conducta. Este Protocolo proporciona servicios de transporte encima del IPX que conecta una red de computadoras capa: IPX para datagramas inestables, SPX para las tramas de mensajes fiables orientados a la conexión. 2. Apreciación global de IPX/SPX Esta sección discute cómo usar el API Winsock 2 con la familia de protocolos IPX. Tradicionalmente, la 1

especificación del Winsock 1.x se ha usado con la familia de protocolos IP como TCP y UDP. Sin embargo, con el advenimiento de Winsock 2, el API se ha actualizado para acceder una gama amplia de transportes y tipos de la red más fácilmente. El API Winsock 2 es suficientemente genérico que los programadores necesitan saber muy poco sobre las especificaciones de la implementación de IPX/SPX. Es obvio que las redes de IPX operan diferente que una red IP, y un poco de consideración de este hecho probablemente será evidente en los códigos. 2.1. La Familia de Direcciones AF_IPX Las familias de direcciones IPX definen la estructura de direccionamiento para protocolos que usan direccionamiento por socket estándar IPX. Para estos transportes, una dirección endpoint consiste en un número de la red, dirección del nodo y número del socket. El número de la red es un dominio administrativo y típicamente nombrados como solo ethernet o un segmento de token ring. El número del nodo es la dirección física de una estación. La combinación de red y nodo, forma una única dirección de la estación que se presume ser única en el mundo. Los números Red/nodo se representan en bloques ASCII o la anotación dashed como: 0101a040, 00001b498765 o 01−01−a0−40,00−00−1b−49−87−65. La necesidad de cero Principal no está presente. El número de socket IPX es un número de servicio de Res/transporte tal como un número de puerto TCP y no debe ser confundido con el descriptor de socket Winsock. Los números de Socket IPX son globales para la estación extremo y no pueden ligarse a las direcciones del Red/nodo específicas. Por ejemplo, si la estación extremo tiene dos tarjetas de red, un socket limite puede enviar y puede recibir en ambas tarjetas. En particular, los datagramas del socket recibirían los datagramas de la transmisión en ambas tarjetas. Sockaddr_ipx tiene un largo de 14 bytes y es más corto que la estructura de referencia sockaddr de 16 bytes. Las aplicaciones de IPX/SPX pueden aceptar la longitud de 16 bytes así como la verdadera longitud. Si se usa el Sockaddr_ipx y una longitud codificada dura de 16 bytes, la aplicación puede asumir que tiene acceso a los dos bytes que siguen su estructura. Valores de los campos. sa_family Familia de Direcciones AF_IPX en el orden del host. sa_netnum identificador de red IPX en el orden de la red. sa_nodenum Dirección del nodo. sa_socket número de socket IPX en el orden de la red. 2.2. Familia de Identificadores de Protocolo de IPX El parámetro protocolar en socket() y WSASocket() es un identificador que establece un tipo de red y un método para identificar los varios protocolos de transporte que corren en la red. Distinto de IP, IPX no usa un solo valor protocolar para seleccionar una pila de transporte. No hay ningún requisito de la red para usar un valor específico para cada protocolo de transporte, uno es libre de asignarlos de una manera conveniente para las aplicaciones de Winsock. Se evitan valores entre 0 ..255 para evitar colisiones con los valores protocolares PF_INET correspondientes. Nombre Valor Tipo Socket Descripción Reservado

0−255

Reservados para los valores protocolares de PF_INET. 2

NSPROTO_IPX

1000 − 1255

SOCK_DGRAM Datagrama para IPX. SOCK_RAW SOCK_STREAM

NSPROTO_SPX 1256 SOCK_SEQPKT

Intercambio del paquete fiable que usa paquetes fijo−clasificados según tamaño.

Nótese que cuando NSPROTO_SPX se especifica, el protocolo SPX II se utilizará automáticamente si ambos endpoints son capaces de hacerlo. 2.3. Transmisión a Red Local. Una transmisión puede hacerse a la red localmente atada poniendo sa_netnum a binario 0 y sa_nodenum a binario 1. Esta transmisión puede enviarse a la red primaria para el dispositivo, o todos ataron redes localmente a la opción del proveedor de servicio. Las transmisiones a la red local no son propagadas por routers. 2.4. Transmisión a todas las rutas. Una transmisión general a través del internet es lograda poniendo los sa_netnum y campos del sa_nodenum a binario 1. El proveedor de servicio traduce esta demanda a un paquete del tipo 20 que las routers de IPX reconocen y remiten. Su paquete visitará todas las subredes y puede duplicarse varias veces. Los receptores deben manejar muchas copias duplicadas de su datagrama. El uso de este tipo de la transmisión es muy impopular entre administradores de la red y su uso debe estar sumamente limitado. Muchos routers desactivan este tipo de transmisión y dejan invisible su paquete a partes de la subred. 2.5. Transmisión Dirigida. Generalmente considerado más red−amistoso que la transmisión a todas las rutas, una transmisión dirigida limita la transmisión a la red local que usted especifica. Llene sa_netnum del número de la red designado y sa_nodenum con binario 1. Las Routers remiten esta demanda a la red del destino donde se vuelve una transmisión local. Las redes del intermedio no ven este paquete como una transmisión. 2.6. Algo sobre el Tamaño de Paquete de comunicación. El tamaño de paquete de medios de comunicación afecta la habilidad de protocolos de IPX de transferir datos por las redes y puede nos puede desafiar a tratar con una manera de transporte independiente. IPX no segmenta paquetes, ni informa cuando se dejan caer paquetes por violaciones del tamaño. Esto significa que alguna entidad en una estación del extremo debe mantener el conocimiento del tamaño máximo de paquete a ser usado en cualquier camino de la interred. Tradicionalmente, el datagrama de IPX y los servicios orientados a la conexión SPX, han dejado esta carga a la aplicación, mientras SPXII ha usado negociación de Paquete Internet Grande para manejarlo transparentemente. Winsock intenta poner límites racionales de tamaño de paquete para sus varios protocolos de IPX como se vera a continuación. Estos límites pueden verse y pueden ser modificados por aplicaciones vía las opciones de socket de get/set. Al determinar tamaño máximo de paquete, las tres áreas de preocupación son: • El tamaño de paquete de medios de comunicación • El tamaño paquete Routable 3

• El tamaño de paquete de extremo−estación El tamaño de paquete de medios de comunicación refleja el tamaño de paquete máximo aceptable en cualquier medio de comunicación. El tamaño del paquete varía entre medios de comunicación como ethernet y token ring. La cantidad de espacio de los datos dentro de un paquete también puede variar dentro de un medios de comunicación dados y puede depender del arreglo de título de paquete. Por ejemplo, los datos eficaces clasifican según tamaño de un paquete del ethernet varía y depende adelante si es de tipo Ethernet II, Ethernet 802.2 o Ethernet SNAP. El tamaño paquete Routable refleja el tamaño máximo de paquete que una router puede remitir. Se construyen routers de IPX modernas para dirigir cualquier tamaño del datagrama que con tal de que permanezca dentro de la red. Sin embargo, las routers más viejas pueden limitar tamaño máximo de paquete a 576 bytes, incluyendo los títulos protocolares. El tamaño de paquete de extremo−estación refleja el tamaño de los buffer del los extremo−estación que están en espera y han anunciado para recibir paquetes entrantes. Incluso cuando los medios de comunicación y límites de la router permiten un paquete a través de, puede ser desechado por el extremo−estación si la aplicación receptor ha anunciado un buffer más pequeño. Muchas aplicaciones de IPX/SPX tradicionales limitan tamaño del buffer de recepción tal que la porción de los datos no debe ser más grande que 512 o 1024 bytes. 3. Cable coaxial Con respecto a las conexiones de red del tipo coaxial, la especificación IEEE 802.3 es clara: "La MAU debe proporcionar aislamiento entre los circuitos de la capa física del DTE y el cable troncal coaxial. La impedancia de aislamiento medida entre cada conductor en los circuitos de la capa física del DTE y tanto el conductor central como el blindaje del cable coaxial debe ser mayor que 250k ohmios a 50, 60 Hz. Además la impedancia de aislamiento entre la tierra del DTE y el blindaje del cable coaxial debe ser menos de 15 ohmios entre 3 Mhz y 30 Mhz. Los medios de aislamiento deben soportar 500 Vac rms durante un minuto." Estándar IEEE 802.3 Al contrario de otras conexiones con el equipo de usuario, tales como módems o video, la conexión Ethernet está totalmente aislada del equipo del usuario. La primera indicación de este hecho es que el espigo del conector hembra montado en el chasis está aislado del mismo por medio de un anillo plástico. En una tarjeta adaptadora para Ethernet, se dedica una sección especial aislada rodeada de áreas de espaciamiento para la interfaz coaxial. Unos aisladores especiales de alto voltaje en la tarjeta sirven de puente sobre el área de espaciamiento y permiten la comunicación entre la estación del usuario y la interfaz coaxial. Este sistema brinda excelente inmunidad ante daños relacionados con sobretensiones, excepto cuando estas sean muy grandes. Con el fin de limitar la magnitud del voltaje que puede existir entre el cable Ethernet y la estación del usuario, los adaptadores Ethernet están equipados con un supresor de sobretensiones de alto voltaje del tipo "spark gap". Para sobretensiones de más de 2000 voltios, este supresor se activará y derivará el pico hacia el chasis de la estación del usuario con el fin de evitar la ruptura del adaptador Ethernet. Desafortunadamente el pico de energía inyectado en el chasis por este supresor de sobretensiones puede hacer que otros puertos en la estación de trabajo se dañen, particularmente los puertos RS−232 que están conectados a otros equipos aterrizados tales como impresoras o plotters (los puertos conectados a equipo no aterrizado, tales como un ratón, no se dañarán). La conexión Thin Ethernet por estándar debe tener una conexión de baja impedancia a través de la barrera de aislamiento, para las altas frecuencias (ver la nota posterior). Esto se logra usando un filtro con condensador. La consecuencia desafortunada de tener este condensador es que el ruido de alta frecuencia se acopla entre el chasis del nodo de red y el cableado Ethernet. Esto permite que el ruido de tierra 4

inter−sistema penetre a la red, lo cual puede interrumpir las comunicaciones de datos. El estándar IEEE 802.3 especifica que cualquier segmento coaxial Ethernet que esté interconectado, debe ser aterrizado sólidamente (a tierra física) y en un solo lugar. Esta importante condición ayuda a reducir el ruido de tierra inter−sistema, aunque es llevada a la práctica muy raramente. Los administradores de la red deberían conocer la localización del punto de tierra del Ethernet y verificar que es el único punto de tierra desconectándolo periódicamente y probando la ausencia de continuidad a tierra por medio de un probador de continuidad. 4. Códigos de los programas de Comunicación: Los programas a continuación descritos utilizan Winsock propio de cada uno de los lenguajes, y ocupando una librería de manejo del protocolo IPX. Para la comunicación se utilizaron llamados a la API de Windows, específicamente a Winsock, la cual permite comunicar maquinas. Se utilizaron las siguientes funciones de winsock: WSAStartup: La función WSAStartup inicia el uso del DLL Windows Sockets para un proceso. int WSAStartup ( WORD wVersionRequested, LPWSADATA lpWSAData ); Parámetros wVersionRequested [in] La mas reciente versión de Windows Sockets que el programa puede usar. El byte alto indica la revisión, el byte bajo indica la versión. lpWSAData [out] Un puntero a la estructura de datos WSADATA que va a recibir los detalles de la implementación de Windows Sockets. Socket: La función Socket crea un socket que esta enlazado a un respectivo proveedor de servicios. SOCKET socket ( int af, int type, int protocol ); 5

Parámetros af [in] Una especificación de familia de direcciones. type [in] Un tipo de especificación para el nuevo socket. protocol [in] Un protocolo en particular para ser usado que es especifico a la familia de direcciones. Setsockopt La función setsockopt configura el socket. int setsockopt ( SOCKET s, int level, int optname, const char FAR * optval, int optlen ); Parámetros s [in] Un descriptor que identifica al socket. level [in] El nivel en el cual la opción es definida los niveles soportados son SOL_SOCKET y IPPROTO_TCP. optname [in] La opción del socket la cual va a ser seteada. optval [in] Un puntero al buffer en el cual esta el valor de la opción que se va a setear. optlen [in] El tamaño del buffer optval. Bind La función Bind asocia una dirección local con un socket. int bind ( SOCKET s, const struct sockaddr FAR* name, int namelen ); 6

Parámetros s [in] Un descriptor identificando al socket no asociado. name [in] La dirección para asignar el socket. La estructura sockaddr se define por los siguientes campos: sa_netnum, sa_nodenum, siipx.sa_socket, sa_family namelen [in] El largo de name. ioctlsocket Esta función controla el modo del socket. int ioctlsocket ( SOCKET s, long cmd, u_long FAR* argp ); Parámetros s [in] Un descriptor que identifica a un socket. cmd [in] El comando a realizar en el socket s. argp [in/out] Un puntero a un parámetro para cmd. shutdown Esta función desabilita enviar y/o recibir en un socket. int shutdown ( SOCKET s, int how ); Parámetros s[in] Un descriptor que identifica a un socket. how[in] Una bandera que indica que operación va a ser desactivada. Closesocket Esta función cierra un socket. 7

int closesocket ( SOCKET s ); Parámetros s[in] Un descriptor que identifica a un socket. WSACleanup Termina el uso del windows socket DLL. int WSACleanup (void); sendto Esta función envía datos a una destinación especifica. int sendto ( SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR * to, int tolen ); Parámetros s[in] Un descriptor que identifica a un socket. buf[in] Un buffer que contiene los datos a ser trasmitidos. len[in] El largo de los datos en buf. flags[in] Especifica el modo en que la llamada es hecha. to[in] Un puntero opcional a la dirección del socket objetivo. tolen[in] El tamaño de la dirección en to. Recvfrom

8

Esta función recibe un datagrama y guarda la dirección que lo envio. int recvfrom ( SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR* from, int FAR* fromlen ); Parámetros s[in] Un descriptor que identifica a un socket. buf[out] Un buffer que contiene los datos a ser recibidos. len[in] El largo de los datos en buf. flags[in] Especifica el modo en que la llamada es hecha. from[out] Un puntero opcional a una dirección con la dirección que envía. fromlen[in/out] El tamaño de la dirección en from. Código del programa en Visual Basic 6.0 Option Explicit Private Sub Form_Load() Dim RetVal As Integer RetVal = vbIPXInitialize(Socket) 'Inicializa IPX If RetVal = 0 Then 'Chequea si la inicialización fue exitosa. 0 = No, 1 = Si MsgBox "IPX: Fallo la Iniciación" End End If Text1.SelText = "IPX init: Exitoso" & vbCrLf

9

Text1.SelText = "Socket: Open Port: " & Socket & vbCrLf Text1.SelText = "Socket: Esperando" & vbCrLf Text1.SelText = "MaxPacketSize: " & vbIPXGetMaxPacketSize & vbCrLf & vbCrLf Text2.MaxLength = 128 'Largo máximo del Mensaje. End Sub Private Sub Form_Unload(Cancel As Integer) vbIPXShutdown End Sub Private Sub Text2_KeyPress(KeyAscii As Integer) If (KeyAscii = 13) Then 'Si se Presiona enter KeyAscii = 0 If Text2.Text = "" Then Exit Sub 'No enviar un string vacío BroadCast (Text2.Text) 'Convertir el texto y enviarlo a todos Text1.SelText = "LOCAL:" + Text2.Text + vbCrLf Text2.Text = "" 'Limpiar la typebox End If End Sub Private Sub Timer1_Timer() Dim RetVal As Integer, Packet As PacketType Dim i As Long Dim Node As String, PacketStr As String RetVal = vbIPXCheckForPacket(Packet) 'Existe un paquete esperando If RetVal = 1 Then ' 1 = Si PacketStr = GetMsg(Packet) 'Recibir el Mensaje For i = 1 To 6 Text1.SelText = Format(Hex(Packet.Node(i)), "00") + ":"

10

Next i Text1.SelText = PacketStr & vbCrLf End If End Sub Modulos: IPX2.bas Public Const Socket As Long = &HFF Public Sub BroadCast(Message As String) Dim Packet As PacketType Dim i As Long Packet.data(0) = Len(Message) 'Se debe enviar el largo del mensaje For i = 1 To Packet.data(0) Packet.data(i) = Asc(Mid(Message, i, 1)) 'Convierte Chars a Ints Next i vbIPXBroadcastPacket Packet 'Enviar el paquete End Sub Public Function GetMsg(Packet As PacketType) As String Dim PacketStr As String For i = 1 To Packet.data(0) 'Leer todos los chars PacketStr = PacketStr & Chr(Packet.data(i)) 'Convertir y concatenar. Next i GetMsg = PacketStr 'Retornar el mensaje End Function VBNet.bas Type PacketType Node(1 To 6) As Byte

11

data(300) As Byte End Type Declare Function vbIPXInitialize Lib "vbnet32" (ByVal Socket As Integer) As Integer Declare Function vbIPXGetMaxPacketSize Lib "vbnet32" () As Integer Declare Function vbIPXCheckForPacket Lib "vbnet32" (paket As PacketType) As Integer Declare Sub vbIPXStartListening Lib "vbnet32" () Declare Sub vbIPXStopListening Lib "vbnet32" () Declare Sub vbIPXShutdown Lib "vbnet32" () Declare Sub vbIPXBroadcastPacket Lib "vbnet32" (paket As PacketType) Declare Sub vbIPXSendPacket Lib "vbnet32" (paket As PacketType) Código del programa en C ++ Builder 4 //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− #include #pragma hdrstop #include "Unit1.h" //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− #pragma package(smart_init) #pragma resource "*.dfm" #include #include #include #include // tamaño maximo de un paquete #define MAILPACKETSIZE 300 // El ipx no esta inicializado int initialized=0;

12

// struct IPXPacket − Esta es la estructura del paquete que vamos a enviar. struct IPXPacket { BYTE node[6]; BYTE data[MAILPACKETSIZE+1]; }; SOCKET sockhandle; SOCKET Sock=0xff; WSADATA wsadat; unsigned oursocknum=0x8849; SOCKADDR_IPX siipx; TForm1 *Form1; // showerrorbox − muestra un mensaje con el error y luego sale del proceso void showerrorbox(char*mmm) { MessageBox(NULL,mmm,NULL,MB_TASKMODAL | MB_OK); ExitProcess(1); } // inicializa el ipx short IPXInitialize(UINT socc) { if (initialized) return 0; //si ya esta inicializado sale if (WSAStartup(0x101,&wsadat)) showerrorbox("Error en inicio del Socket Windows"); //inicializa el uso del DLL para el programa sockhandle=socket(AF_IPX,SOCK_DGRAM,NSPROTO_IPX); //crea un socket IPX para el programa if (sockhandle==INVALID_SOCKET) showerrorbox("Error en initSocket"); // oursocknum=socc; // int dobroad=1; //broadcast activado if (setsockopt(sockhandle,SOL_SOCKET,SO_BROADCAST,(char FAR*)&dobroad,sizeof(int))) //activa el broadcast

13

showerrorbox("Error en SetSockOpt"); //Limpia las direcciones para realizar el bind memset(siipx.sa_netnum,0,4); //netnum=0.0.0.0 memset(siipx.sa_nodenum,0,6); //nodenum=00.00.00.00.00.00 siipx.sa_socket=oursocknum; //socket=socc siipx.sa_family=AF_IPX; //familia=AF_IPX WSASetLastError(0); //Enlaza el socket de windows a nuestro socket ipx if (bind(sockhandle,(LPSOCKADDR)&siipx,sizeof(SOCKADDR))) { //enlaza sockhandle a la direccion de siipx closesocket(sockhandle); //cierra el socket si hay un error WSACleanup(); //limpia Windows socket showerrorbox("Error en bindSocket"); } u_long nonblockingmode=1; //nonblocking activado //Inicializa el socket para I/O if (ioctlsocket(sockhandle,FIONBIO,&nonblockingmode)) //setea el nonblocking en nuestro socket showerrorbox("Error en ioctlsocket"); initialized=1; return 1; } // vbIPXShutdown − cierra el socket y termina el socket de windows void IPXShutdown() { if (initialized==0) return; if (shutdown(sockhandle,2)) showerrorbox("Error en socket Shutdown"); //desactiva el envio en el socket if (closesocket(sockhandle)) showerrorbox("Error en closesocket"); //cierra el socket WSACleanup(); //termina el uso del DLL Windows socket 14

initialized=0; } // BroadcastPacket − manda un paquete a todo computador en el mismo segmento de red void IPXBroadcastPacket(IPXPacket*ipxpak) { siipx.sa_family=AF_IPX; //familia=AF_IPX memset(siipx.sa_netnum,0x0,4); //netnum=0.0.0.0 memset(siipx.sa_nodenum,0xff,6); //nodenum=FF.FF.FF.FF.FF.FF(broadcast) siipx.sa_socket=oursocknum; //socket=oursocknum if (sendto(sockhandle,(char FAR*)&ipxpak−>data[0],MAILPACKETSIZE−1,0,(sockaddr FAR*)&siipx,14)==SOCKET_ERROR) //envia el paquete showerrorbox("Error en Broadcast"); } // CheckForPacket − revisa si existe un paquete y si existe lo copia dentro de el registro short IPXCheckForPacket(IPXPacket*ipxpak) { int sizz=14; //tamaño del paquete = 14 memset(siipx.sa_nodenum,0xff,6); //nodenum=FF.FF.FF.FF.FF.FF(broadcast) siipx.sa_family=AF_IPX; //familia=AF_IPX siipx.sa_socket=oursocknum; //socket=oursocknum if (recvfrom(sockhandle,(char FAR*)&ipxpak−>data[0],MAILPACKETSIZE,0,(LPSOCKADDR)&siipx,&sizz)==SOCKET_ERROR) { //recive el paquete si existe if (WSAGetLastError()!=WSAEWOULDBLOCK) { char buu[30]; sprintf(buu,"recv error: %d",WSAGetLastError()); showerrorbox(buu); } return 0; } memcpy(ipxpak−>node,siipx.sa_nodenum,6); //copia la dirección de donde se recibio 15

return 1; } //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− void __fastcall TForm1::FormActivate(TObject *Sender) { Memo1−>Clear(); Memo1−>Lines−>Add("IPX init: Success"); Memo1−>Lines−>Add("Socket: Open Port: 255"); Memo1−>Lines−>Add("Socket: Listening"); Memo1−>Lines−>Add("MaxPacketSize: 300"); IPXInitialize(Sock);} //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key) { IPXPacket pak; int largo,i; if(Key==13) { Key=0; largo=Edit1−>Text.Length(); pak.data[0]=largo; for (i=1;i<=largo;i++)pak.data[i]=Edit1−>Text[i]; IPXBroadcastPacket(&pak); Edit1−>Text="";

16

}; } //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− void __fastcall TForm1::Timer1Timer(TObject *Sender) { IPXPacket pak; int i; AnsiString node; AnsiString msg; if (IPXCheckForPacket(&pak)) { Memo1−>Text=Memo1−>Text+"\r\n"; for (i=0;i<6;i++) node=node+IntToHex(int(pak.node[i]),2)+":"; for (i=1;i<=pak.data[0];i++) msg=msg+char(pak.data[i]); Memo1−>Lines−>Add(node+msg); } } Código del programa en Delphi 5 unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, winsock, StdCtrls, IPXUnit, ExtCtrls; const // tamaño maximo de un paquete

17

Mailpacketsize=300; // IPXPacket − Esta es la estructura del paquete que vamos a enviar. type ipxpacket=record node : array[0..6] of byte; data : array[0..300] of byte; end ; TSockAddrIPX = record sa_family : short; sa_netnum : array [0..3] of Byte; sa_nodenum : array [0..5] of Byte; sa_socket : u_short; end; TForm1 = class(TForm) Edit1: TEdit; Memo1: TMemo; Timer1: TTimer; GroupBox1: TGroupBox; procedure FormActivate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); private { Private declarations } public { Public declarations }

18

initialized:boolean; sockhandle:tsocket; sock:tsocket; oursocknum:tsocket; wsadat :TWSAdata; siipx:TsockAddrIPX; end; var Form1: TForm1; initialized:boolean; sockhandle:tsocket; sock:tsocket; oursocknum:tsocket; wsadat :TWSAdata; siipx:PsockAddrIPX; ipxpak:ipxpacket; implementation {$R *.DFM} // showerrorbox − muestra un mensaje con el error y luego sale del proceso procedure showerrorbox(s:string); begin Application.MessageBox(pchar(s),('Error'),MB_OK); ExitProcess(1); end; procedure TForm1.FormActivate(Sender: TObject); var

19

i:integer; nonblockingmode:u_long; begin Memo1.clear; Memo1.lines.add('IPX init: Exitoso'); Memo1.lines.add('Socket: Open Port: 255'); Memo1.lines.add('Socket: Listening'); Memo1.lines.add('MaxPacketSize: 300'); Memo1.lines.add(''); Edit1.text:=''; // inicializa el ipx Sock:=$ff; oursocknum:=$8849; if (WSAStartup($101,wsadat)=SOCKET_ERROR) then showerrorbox('Windows Sockets startup failed'); sockhandle:=socket(AF_IPX,SOCK_DGRAM,NSPROTO_IPX); if (sockhandle=INVALID_SOCKET) then showerrorbox('initSocket failed'); oursocknum:=sock; i:=1; if (setsockopt(sockhandle,SOL_SOCKET,SO_BROADCAST,@i,sizeof(integer))=SOCKET_ERROR) then showerrorbox('SetSockOpt failed'); for i := 0 to 3 do siipx.sa_netnum[i] := $0; for i := 0 to 5 do siipx.sa_nodenum[i] := $0; siipx.sa_socket:=oursocknum;

20

siipx.sa_family:=AF_IPX; WSASetLastError(0); // bind the Windows socket to our IPX socket if (bind(sockhandle,PSockAddr(@siipx)^,sizeof(TSockAddrIPX))=SOCKET_ERROR) then begin closesocket(sockhandle); WSACleanup(); showerrorbox('bindSocket failed'); end; nonblockingmode:=1; // Initialize socket for I/O if (ioctlsocket(sockhandle,FIONBIO, nonblockingmode)=SOCKET_ERROR)then showerrorbox('ioctlsocket failed'); end; procedure TForm1.Timer1Timer(Sender: TObject); var sizz,i:integer; msg,node:string; begin sizz:=14; if (recvfrom(sockhandle,ipxpak.data[0],MAILPACKETSIZE,0,PSockAddr(@siipx)^,sizz)=SOCKET_ERROR) then begin if (WSAGetLastError()<>WSAEWOULDBLOCK) then Application.MessageBox(pchar('Recive Error'),('Error'),MB_OK); end

21

else begin node:=''; msg:=''; for i := 0 to 5 do begin ipxpak.node[i]:=siipx.sa_nodenum[i]; node:=node+inttohex(siipx.sa_nodenum[i],2)+':'; end; for i:=1 to ipxpak.data[0] do msg:=msg+chr(ipxpak.data[i]); memo1.lines.add(node+msg); end end; procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var pak:ipxpacket; i:integer; begin if Key=13 then begin pak.data[0]:=length(edit1.text); for i:=1 to length(edit1.text) do pak.data[i]:=ord(edit1.text[i]); for i := 0 to 3 do

22

siipx.sa_netnum[i] := $ff; for i := 0 to 5 do siipx.sa_nodenum[i] := $ff; if (sendto(sockhandle,pak.data[0],MAILPACKETSIZE−1,0,PSockAddr(@siipx)^,14)=SOCKET_ERROR) then showerrorbox('Sendto (Broadcast) Failed'); edit1.text:=''; end; end; end. 5. Conclusiones: Luego de elaborar este trabajo y desarrollar los programas en los distintos lenguajes nos dimos cuenta de la importancia de los protocolos de comunicación para establecer una red. Lo más difícil fue encontrar librerías que nos permitieran trabajar en los distintos lenguajes, después de buscar encontramos una Liberia VBNET hecha en C++, que le daba las funciones de IPX a programas en Visual Basic, a partir de esta librería, que estaba bajo una licencia GNU, se pudo entender como se trabaja con los Sockets de Windows y pudimos extender la aplicación a distintos lenguajes como C++ y Delphi, utilizando la poderosa librería Winsock que es la que gobierna todas las comunicaciones de Windows, no pudimos entrar mas a fondo ya que como esta librería es un DLL de Microsoft, no se permite ni siquiera ver el código fuente de esta. La investigación y la información sobre IPX es muy poca, por ser este un protocolo casi obsoleto y solo utilizado en redes Novell, la implementación de este protocolo en los distintos lenguajes fue mas o menos complicada, ya que el winsock esta hecho mas para TCP y no existen objetos IPX, por lo que tuvimos que entrar mas a fondo para poder realizar la comunicación. La implementación en Visual Basic se realizo utilizando la librería VBNET32 que incorporaba objetos con soporte IPX, esta fue la más fácil ya que no se necesito ingresar en las llamadas a winsock. En C++, tuvimos que adaptar dicha librería para que funcionara, esto lo hicimos mirando los fuentes y viendo como funcionaban los adaptamos a nuestro programa. En Delphi tuvimos que a traducir el código C++, lo cual no fue muy fácil debido a que C++ es un lenguaje mucho más potente y con un manejo de memoria mucho mas claro que Delphi. Lo más agradable para nosotros fue que todas las versiones del programa podían comunicarse entre sí, ya que teníamos la misma estructura de paquete y los mismos puertos, esto fue muy satisfactorio. Existe un problema al realizar el programa en GCC, ya que para que Linux acepte el protocolo IPX es necesario recompilar el Kernel, tarea que no logramos concretar, a pesar de estar bien documentada, pero incluso en los HOWTO de Linux decía que esta era una tarea mas o menos complicada. 23

La implementación en Java no se pudo realizar debido a que los sockets de Java no soportan IPX, solo TCP, para llevar a cabo esto se deberían crear librerías desde cero lo cual no pudimos hacer debido a que no tenemos un amplio conocimiento de dicho lenguaje y la maquina virtual de Java. 6. Bibliografía Ayuda de C++, Delphi Microsoft Developer Network Internet: http://developer.novell.com/support/winsock/doc/wsanx−1.htm http://altavista.com/ http://www.google.com/ http://www.yahoo.com http://members.xoom.com/dosuser/vbipx.htm http://www.apress.ru/pages/bokovikov/delphi/indexe.html

24

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.