Netzwerkprogrammierung mit ipx
Netzwerkprogrammierung mit IPX
Das IPX (Internetwork Packet Exchange) Protokoll ist eine Umsetzung des Internetworkpacket-Protokolls von Xerox. Der Zweck von IPX ist es Applikationen die Möglichkeit zu geben im Netzwerk mit anderen Rechnern und Geräten zu kommunizieren. Dieses Protokoll stellt eine Schnittstelle für Anwendungs-programme, zum Empfang und Senden von Informationen im Netzwerk, zur Verfügung . Diese Informationen setzen sich aus Pakete zusammen, die nacheinander übertragen werden und Daten sowie einen Organisations-block, der aus IPX-header und Event Control Block (ECB), besteht. Diese Pakete haben eine minimale Größe von 30 und maximal von 576 Byte. Jedem Rechner ist eine eindeutige Adresse zugeordnet mit der er Daten von jedem anderen Rechner empfangen und senden kann, sofern er IPX unterstützt.
Der physikalische Transport geschieht automatisch und transparent. Das Protokoll versucht die beste Möglichkeit die Ressourcen auszuschöpfen, aber kann keinen Transport garantieren, dieser muß von der Anwendung kontrolliert und gegebenenfalls wiederholt werden. IPX unterstützt alle Netzwerkarten, die auch von Novell Netware 2.0 unterstützt werden.
IPX benötigt viele Parameter im Bigendian Format, dieses unterscheidet sich vom Format in dem INTEL die Werte in den Variablen ablegt. Um das Bigendian Format zu erhalten muß die Reihenfolge der Bytes vertauscht werden.
Die von IPX zur Verfügung gestellten Funktionen werden über den Interrupt $7A aufgerufen. Damit diese Funktionen zur Verfügung stehen, muß ein Netzwerktreiber(TSR), wie z.B. IPX.EXE speicherfest in den RAM geladen werden.
Net address field
Name
Size(Byte)
Description
network
4
Netzadresse
node
6
Rechneraddresse
socket
2
Socketnummer
In der Struktur -Net address field- wird die Netzadresse des Rechners oder Gerätes gespeichert, dazu gehört die Netzwerk und die Nodeaddresse(Benutzeradresse), sowie die Socketnummer.
IPXheader :
Name
Size(Byte)
Description
Check
2
Bigendian Checksummme
Length
2
Bigendian-Länge des Paketes
tc
1
Transport Kontrolle
pType
1
Paket Type
dest
12
Adresse des Zieles
src
12
Adresse der Quelle
Der IPXheader enthält Informationen über das Paket das versendet oder empfangen werden soll.
Format of the ECB
Name
Size(Byte)
Description
Link
4
Pointer zum nächsten ECB
ESR
4
Pointer zur Event Service Routine
InUse
1
ECB Status
complete
1
ECB Ende-Status
socket
2
Bigendian Socket Nummer
IPXwork
4
Arbeitsspeicher für IPX
Dwork
12
Arbeitsspeicher für Treiber
immedAddr
12
Adresse an die gesendet werden soll
fragCount
2
Anzahl der Datenfragmente
Fragdata
4
Pointer des Datenfragments
Fragsize
2
Größe des Datenfragments
Die event control block Struktur beinhaltet Anzahl, Größe und Zeiger auf Daten, sowie Informationen über die Ausführung des Transports.
Beispiel für Datenteil des Paketes:
struct daten {
char name[10]; Benutzername
char command[10]; Kommandos
char str[80]; Rohdaten
};
Beispiel für Komplettes Paket:
struct packet {
struct ECBType ecb; Event Control Block
struct IPXheader ipx; IPX Header
struct dat data; Datenblock
} ;
IPX-Bibliothek
Diese Bibliothek stellt wichtige Funktionen zur Kommunikation zwischen verschiedenen Rechnern mit den IPX-Protokoll zur Verfügung. Diese sind in der Header-Datei IPX.h zusammengefaßt und in der dazugehörigen IPX.c-Datei implementiert.
Um sie nutzen zu können, muß die IPX.h mit der Anweisung #include “IPX.h” in den Quelltext eingebunden werden. Die obengenannten Strukturen werden von den Funktionen benötigt, sie sind ebenfalls in IPX.h vereinbart.
Der Header stellt folgende Funktionen zur Verfügung:
-Getlocaladdress();
Ermittelt die Nodeadresse des lokalen Rechners und legt sie in der globalen Variable localaddr ab, die aus IPX.
c exportiert wird.
Interruptaufruf :
Übergabeparameter: AH=$0009 ES:Segment der Adresse DS:Offset der Adresse
-void initIPX();
Überprüft das Vorhanden sein des IPX-Protokolls und initialisiert dieses. Die Funktionen werden mit dem Interrupt 7Ah zur Verfügung gestellt.
Hier wird der Multiplexerinterrupt $2F mit AX=$7f00 aufgerufen, um zu überprüfen ob das IPX-Programm (TSR) installiert ist. Im Register AL wird der Rückgabewert abgelegt, beträgt er $FF ist IPX nicht installiert.
-byte IPXopenSocket(byte longevity);
Öffnet einen IPX-Socket und gibt den Fehlerstatus zurück.
Mit longevity kann man angeben wie sich IPX verhalten soll, wenn die Applikation geschlossen wird. Wird 0 übergeben wird der Socket auch geschlossen, wenn das Programm beendet wird. Bei 255 bleibt der Socket in diesem fall offen und muß explizit mit IPXcloseSocket geschlossen werden.
Interruptaufruf :
Übergabeparameter: AH=$0000 AL=Longvity DX=Socketnummer
Ausgabeparameter : AL=Error Code DX=Socketnummer
-void IPXcloseSocket();
Schließt eine mit IPXopenSocket geöffneten IPX-Socket wieder;
Interruptaufruf :
Übergabeparameter: AH=$0001 DX=Socketnummer
-void InitSendPacket(struct ECBType *ecb,struct IPXheader *ipx,word size);
Initialisiert die zum Senden eines Pakets wichtigen Parameter des IPXheaders und des ECB-Blockes. Dazu gehören zum Beispiel die Nodeadresse des Absenders und die Nodeadresse des Empfängers. Sollen alle Teilnehmer angesprochen werden muß die Nodeadresse vollständig auf 255 gesetzt werden.
Dieser Vorgang wird auch Broadcast genannt. Der Socket muß invertiert werden, da er im Bigendianformat übergeben werden muß.
-void IPXsendPacket(struct ECBType *ecb);
Sendet ein Datenpaket das aus einem IPXheader, eine ECB-Block und den Daten besteht. Es muß getestet werden ob das Netzwerk frei ist bevor gesendet wird, damit das Paket nicht verloren geht.
Bsp.: do {} while (send.
ecb.inUse!=0)
Interruptaufruf :
Übergabeparameter: AH=$0003 ES:Segment des ECB’s DS:Offset des ECB’s
-byte IPXListenPacket(struct ECBType *ecb);
Ermittelt, ob ein Paket angekommen ist, und liefert diese Struktur zurück (IPXheader, ECB-Block, Daten).Auch hier muß gewartet werden bis das Netzwerk frei ist !
Interruptaufruf :
Übergabeparameter: AH=$0003 ES:Segment des ECB’s DS:Offset des ECB’s
Rückgabeparameter: AL=Error Code
-void ImIdle()
Signalisiert dem IPX-Treiber daß, das Programm nicht auf das Netzwerk zugreift. Damit kann das Netzwerk entlastet werden.
Interruptaufruf:
Übergabeparameter: AH=$000A
Variablen in IPX.c:
extern struct localaddrT localaddr; Diese Variable speichert die Nodeadresse des lokalen Rechners.
Intern verwendet das IPX.c-Modul die Variablen mysocket und invsocket. In diesen wird die Socketnummer gespeichert. In invsocket ist sie im Bigendian-Format abgelegt.
Beispielprogramm zum Benutzen der IPX-Bibliothek:
#include <stdio.h>
#include <string.
h>
#include "ipx.h" /*IPX-Bibliothek*/
struct packet {
struct ECBType ecb;
struct IPXheader ipx;
char data[80];
} send,receive;
void main()
{
if (initIPX()==255)
{
switch (IPXopenSocket(0))
{
case 0: printf("Socket etabliert\n");break;
case 255:printf("Socket bereits offen\n");break;
case 254:printf("Sockettabelle voll\n");break;
}
InitSendPacket(&send.ecb,&send.ipx,sizeof(send.data));
InitReceivePacket(&receive.ecb,&receive.
ipx,sizeof(receive.data));
/*** Senden von Daten ***/
printf(“Daten zum senden(Leerstring=nicht senden) :”);
scanf(“%s”,&send.data);
if (strlen(send.data)!=0)
{
/**** Erhalte Daten, wenn Netzwerk frei ist ***/
do {} while (send.ecb.inUse!=0)
IPXsendPacket(&send.
ecb);
}
if (IPXListenPacket(&receive.ecb)!=0)
printf("Fehler beim Versuch ein Packet zu erhalten !");
else
printf(“Daten wurden empfangen: %s”,receive.data);
IPXcloseSocket();
}
IPX-Bibliothek Buchhorn/Jüngel
#include <dos.h>
#include "ipx.h"
struct localaddrT localaddr;
word mysocket=0x869c; /* offizielles Doom Socket */
word invsocket=0x9c86;
union REGS regs;
struct SREGS sregs;
/****** Ermittelt lokale Adresse *******/
void Getlocaladdress()
{
regs.x.
bx= 9;
sregs.es =FP_SEG(&localaddr);
regs.x.si = FP_OFF(&localaddr);
int86x(0x7A,®s,®s,&sregs);
}
/******* Initalisiert IPX ******/
void initIPX()
{
regs.x.ax=0x7a00;
int86x(0x2f,®s,®s,&sregs);
if (regs.
h.al!=255)
printf("\nFehler beim Initialiesieren von IPX \n");
else printf("IPX initalisiert \n");
Getlocaladdress();
}
/********** öffnet IPX Socket und šbergibt Al-Register **********/
byte IPXopenSocket(byte longevity)
{
byte status;
regs.x.bx=0x0000;
regs.h.al=longevity;
regs.
x.dx=invsocket;
int86x(0x7a,®s,®s,&sregs);
status=regs.h.al;
return (status);
}
/******* Schließt IPX Socket ********/
void IPXcloseSocket()
{
regs.x.bx=0x0001;
regs.
x.dx=invsocket;
int86x(0x7a,®s,®s,&sregs);
}
/****** Initialisierung von SendPacket ******/
void InitSendPacket(struct ECBType *ecb,
struct IPXheader *ipx,word size)
{
byte i;
memset(ecb,0x0000,sizeof(*ecb));
memset(ipx,0x0000,sizeof(*ipx));
ecb->socket=invsocket;
ecb->fragCount=1;
ecb->fragData=ipx;
ecb->fragSize=sizeof(*ipx)+size;
for(i=0;i<6;ecb->immedAddr[i]=255,i++);
ipx->check=0xffff;
ipx->pType=0;
for(i=0;i<4;i++,ipx->dest.net[i]=localaddr.net[i]);
for(i=0;i<6;i++,ipx->dest.node[i]=0xff);
ipx->dest.socket=invsocket;
for(i=0;i<4;i++,ipx->src.
net[i]=localaddr.net[i]);
for(i=0;i<6;i++,ipx->src.node[i]=localaddr.node[i]);
ipx->src.socket=invsocket;
}
/**** Sende Packet ***************/
void IPXsendPacket(struct ECBType *ecb)
{
regs.x.
bx=0x0003;
sregs.es=FP_SEG(ecb);
regs.x.si=FP_OFF(ecb);
int86x(0x7a,®s,®s,&sregs);
}
/**** Warte auf Packet ***************/
byte IPXListenPacket(struct ECBType *ecb)
{
byte status;
regs.x.bx=0x0004;
sregs.
es=FP_SEG(ecb);
regs.x.si=FP_OFF(ecb);
int86x(0x7a,®s,®s,&sregs);
status=regs.h.al;
return(status);
}
/******* Bin Frei !!! *******/
void ImIdle()
{
regs.x.
bx=0x000a;
int86x(0x7a,®s,®s,&sregs);
}
/**********Initialiesieren von ReceivePacket *******/
void InitReceivePacket(struct ECBType *ecb,struct IPXheader *ipx,word size)
{
memset(ecb,0x0000,sizeof(*ecb));
memset(ipx,0x0000,sizeof(*ipx));
ecb->inUse=0x1d;
ecb->socket=invsocket;
ecb->fragCount=1;
ecb->fragData=ipx;
ecb->fragSize=sizeof(*ipx)+size;
if (IPXListenPacket(ecb)!=0);
}
Headerdatei IPX.h:
#ifndef __IPX_H
#define __IPX_H
typedef unsigned char byte;
typedef unsigned short word;
typedef byte netaddr[4];
typedef byte nodeaddr[6];
struct netaddress
{ netaddr net;
nodeaddr node;
unsigned int socket;
};
struct localaddrT
{ netaddr net;
nodeaddr node;
};
struct ECBType
{
void far *link;
void far *ESR;
byte inUse;
byte complete;
word socket;
byte IPXwork[4];
byte Dwork[12];
nodeaddr immedAddr;
word fragCount;
void *far fragData;
word fragSize;
};
struct IPXheader{
word check;
word lenght;
byte tc;
byte pType;
struct netaddress dest;
struct netaddress src;
};
extern struct localaddrT localaddr;
void Getlocaladdress();
byte initIPX();
byte IPXopenSocket(byte longevity);
void IPXcloseSocket();
void InitSendPacket(struct ECBType *ecb,struct IPXheader *ipx,word size);
void IPXsendPacket(struct ECBType *ecb);
byte IPXListenPacket(struct ECBType *ecb);
#endif
Headerdatei Tools.h:
#ifndef __IPX_H
#define __IPX_H
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
void Scrolldown (char y1,char y2);
void Scrollup(char y1,char y2);
void win(int x1,int y1,int x2,int y2);
#endif
Benutzeranleitung CHAT 97
Der Benutzer startet mit dem Eingangsbildschirm, wo ihm eine kurze Einführung und Informationen über IPX zur Verfügung gestellt wird.
Weiterhin wird das Benutzerhandle abgefragt, mit dem man sich anmeldet.
Das Programm schickt das Handle, die Adresse und einen Befehlsflag, der auffordert den Header zu schicken, an alle Rechner und meldet sich so bei allen Rechnern an. Ein neuer Textbildschirm wird aufgebaut, der sich in drei Teile gliedert: dem Inputfenster (Daten zum senden), dem Outputfenster (emfangende Daten) und Chatpartnerfenster (zeigt angemeldeten Benutzer).
Man schickt seine eingegebene Nachricht mit Enter oder mit dem Zeilende ab.
Mit den Funktionstasten F1-F10 können Teilnehmer 1-10 und mit Strg + F1-F3, Teilnehmer 10-13 angesprochen werden, die Nachricht erhält also nur dieser Rechner. Die F12-Taste schaltet wieder auf Broadcast um.
Mit <Esc> wird das Programm beendet.
Hauptprogramm
ChatScreen aufbauen
Anmelden des Benutzers
im Netzwerk
Taste einlesen
Abmelden des Benutzers
im Netzwerk
Enter gedrückt/Zeilenende
Funktionstaste gedrückt
Taste übergeben
tue bis Taste gedrückt
oder Daten eingetroffen
Tabelle organisieren
Farbe für Chatpartner bestimmen
Paket auswerten
bzw. ausgeben
Packet holen
Benutzertabelle auf Bildschirm regenerieren
tue bis Escape gedrückt
Sende Daten
Stelle Inputfenster
wieder her
Ordne Funktiontaste einer Adresse zu, bzw. Schalte auf Broadcast um
an send.data.str anfügen
Zeichen im Inputfenster darstellen
Backspace gedrückt
letztes Zeichen in send.
data.str löschen,
Zeichen im VRAM löschen
neuer Name ? dann
-in Tabelle eintragen
-count hochsetzen
Commandflag = 1 dann,
schicke neuem User den Namen und die Adresse
ansonsten
gebe den Namen und seine Nachricht aus
ggf. scrolle Bildschirm
Schicke jedem die Anweisung, den Namen und die Adresse zu senden
Schicke jedem Rechner die Nachricht: Bin abgemeldet
Initaliesiere IPX
SchließeIPXSocket
Initialisiere SendPacket
InitialisiereReceivePacketStartscreen
START
Anmerkungen: |
| impressum | datenschutz
© Copyright Artikelpedia.com