Written by : Peter Quiring (Sept 29/96)
When comunicating with IPX there is always a client (listener) and a server(talker). I'll get to that later but first I'll go over the usually things necessary to start up.
mov ax,7a00h int 2fh .if al==0ffh ;IPX is installed .else ;IPX is NOT installed .endif
Now that you know you can use IPX you can start comunicating. The process is very simple. You open a socket, then you can listen or talk to the socket. IPX networks have 64K sockets but the 1st 32K are used by the Network OSes. The 2nd 32K are free for use. Choosing a socket is important, try not to use one already used by other popular software or the user will not be able to run your software while playing the other games on the same network.
mov ax,0 mov bx,0 mov dx,desired_socket int 7ah ;al=status 0=ok ff=already open fe=socket table full ;dx=socket number given
Once a socket has been opened, you may start using it. Any other program that opens the same socket will be able to comunicate with your program. When sending or receiving packets there are structs needed in order to call the IPX driver with infomation about where to put the data and such. There are two such structs needed. You should have 2 sets of these structs, one set for sending and another for receiving.
ECB struct LinkAddressOff dw ? ;ignore LinkAddressSeg dw ? ;ignore ESRAddressOff dw ? ;leave 0 ESRAddressSeg dw ? ;leave 0 InUse db ? CompCode db ? SockNum dw ? IPXWorkSpc dd ? DrvWorkSpc db 12 dup (?) ImmAdd db 6 dup (?) FragCount dw ? FragAddOfs dw ? FragAddSeg dw ? FragSize dw ? ECB ends IPX struct Checksum dw ? Length dw ? Control db ? PacketType db ? DestNet dd ? DestNode df ? ;6 bytes DestSocket dw ? SourNet dd ? SourNode df ? SourSock dw ? Datagram db packet_size dup (?) IPX endp
ECB.Linkaddressoff - this should be ignored
ECB.Linkaddressseg - this should be ignored
ECB.ESRaddressoff - this should be zero - it's the Event Service Request
ECB.ESRaddressseg - this should be zero
ECB.InUse - this byte will be filled in by the IPX driver when a data packet has been sent/received.
ECB.CompCode - the byte is the status of the last operation
ECB.Socknum - Socket # you want to comunicate over (it must be already open)
ECB.IPXWorkSpc - this should be zero - ??? ECB.DRVWorkSpc - this should be zero - ??? ECB.ImmAdd - this is the server # to comunicate thru, if 0ffffffffffffh is used then the nearest server is used. When you receive a packet this info is filled in with the proper info and should be copied to your ECB send struct.
ECB.FragCount - # of IPX structs are used (use 1 always)
ECB.FragAddoff - offset of your IPX struct
ECB.FragAddseg - segment of your IPX struct
ECB.FragSize - total size of IPX struct (including all data)
IPX.Checksum - should always be zeroed before using with IPX driver
IPX.Length - length of IPX packet (including data)
IPX.Control - set to zero - will be filled in by IPX driver
IPX.PacketType - set to zero(unknown)
IPX.DestNet - set to zero for default network during init and once you receive a packet from another computer fill this area in with it's address
IPX.DestNode - set to 0ffffffffffffh to broadcast to all nodes(computers). Then when you reveice a packet from a computer you can fill this in with it's node #.
IPX.DestSocket - Socket to comunicate on
IPX.SourNet - this is the source of a received packet
IPX.SourNode - this is the source node of a received packet
IPX.SourSock - socket used in received packet
IPX.Datagram - this is the data buffer where you want to send/receive data. The whole IPX header can not be larger than 1024 bytes. Which leaves at max xxxx bytes for data.
;setup ECB and IPX structs mov bx,3 mov es,seg ECB mov si,offset ECB int 7ah
;setup ECB and IPX structs mov bx,4 mov es,seg ECB mov si,offset ECB int 7ah
When sending/receiving packets you must give time to the IPX driver which can be done thru this:
mov ax,0 mov bx,0ah int 7ah
This must be called as many times as needed until the InUse flag in
the ECB struct changes. When this occurs all the elements in the structs
will be filled out by the IPX driver.
The InUse flag will be set to 0ffh by the IPX driver when you use the send or receive command. It will remain that way until an error occurs or it is finished. If it equals zero it was done successfully. Otherwise it was an error. Then you must look at the CompCode to see exactly what happened.
These compeletion codes are set once InUse is set to zero by the IPX driver.
Send Compcodes: 00 sent FC canceled FD malformed packet FE no listener (undelivered) FF hardware failure Receive CompCodes: 00 received FC canceled FD packet overflow FF socket was closed FE Listening
If while trying to send/receive a packet you decide to stop for any
reason you can cancel the operation.
mov bx,6 mov es,seg ECB mov si,offset ECB int 7ah ;al=compcode (should be 0FCh = canceled)
Once you need to quit your application, you'll need to stop communication
between the two (or more) computers.
This tells the other computer you no longer want to talk. This requires
a third struct.
FullNetAddr struct NetWork dd ? Node df ? Socket dw ? FullNetAddr ends
These should be filled out with the listeners addresses properly.
mov bx,0bh mov es,seg FullNetAddr mov si,offset FullNetAddr int 7ah
When ever you are done using a socket you must close it.
mov bx,1 mov ax,0 mov dx,Socket# int 7ah
That is all it really takes to do it !!!
When designing your game you have to choose which method your program will comunicate over the network. You could use a client/server method as most programs do. Or you could just keep using general broadcasting over the network (on one socket of course) but this is very slow.
The best way to do this is to use only one socket, set up your structs to use it and setup for a general broadcast. The data in the packet should let all other computer know you are looking for a program server (not to be confused with the Server on your network). If there is a server already running it should tell the new player and the new player will start to send only to that server. If after some time you don't find a server, set yourself up as a server and begin playing. Although timing is very important here, what if two computers start up the program at the same time. If two servers start up the system will not work. What I would do is if two (or more) computers are looking for a server and there is none then your should roll dice or something.
One last thing, the server should usually be the one of the fastest computers. Therefore if a new player enters the game and has a faster computer you should move the server to it. But remember, don't use the SPEED of the computer to determine the speed of it's network speed. A 386 may be faster than a Pentium if the Pentium is on another LAN connected thru a bridge or something. But you don't have to do all this advanced stuff. Another thing you should do is if there are many people playing and the server quits or crashes then a new server must be assigned again (roll dice?). Older games didn't do this so if the server quit, everyone quits! If you ever played Descent, it would broadcast such a message when the server quited.
And here is IPXCHAT.BAS - a nice little IPX Chat program in BASIC. (requires Quick Basic v4.5)