📄 libnet.txi
字号:
if (net_driverlist_test (detected, names[i].num)) @{ printf ("(detected) "); initialised = net_initdrivers (drivers); if (net_driverlist_test (initialised, names[i].num)) printf ("(initialised) "); @} printf ("\n");@}free (names);/* Destroy the `drivers' list, but not the other lists. */net_driverlist_destroy (drivers);@end example @c ----------------------------------------------------------------@node net_shutdown, , net_initdrivers, Core Functions@subsection net_shutdown@findex net_shutdown@subsubheading Prototype@exampleint net_shutdown (void);@end example@subsubheading PurposeShuts everything down nicely, closing any open channels and shutting down all initialised drivers. @code{net_init} installs an exit function that calls this, so you don't normally need to call it. You do need to call it if for some reason you want to reinitialise the library with adifferent driver set, maybe -- for example, if you needto reinitialise the drivers with a new config file.@subsubheading Return valueReturns 0 on success.@c ----------------------------------------------------------------@node Channel Functions, Connection Functions, Core Functions, Functions@section Channel Functions@cindex channel functions@cindex channel@cindex unreliable communication, functions@cindex low level packet sending@cindex functions, channelThese functions work with communication channels. Whenever you sendor receive data, you do so through a channel. Each channel has an associated network type (which can't be changed after the channel iscreated), a local address (which is controlled by the driver) and atarget address (which the user can change at will).Channels are referred to through pointers to @code{NET_CHANNEL} objects.@menu* net_openchannel:: * net_closechannel:: * net_assigntarget:: * net_getlocaladdress:: * net_send:: * net_receive:: * net_query:: @end menu@c ----------------------------------------------------------------@node net_openchannel, net_closechannel, Channel Functions, Channel Functions@subsection net_openchannel@findex net_openchannel@subsubheading Prototype@exampleNET_CHANNEL *net_openchannel(int type, char *binding);@end example@subsubheading PurposeThis function opens a communications channel for use over the specified network type.@subsubheading Parameters@var{type} is one of the @code{NET_DRIVER_*} constants, for example it could be one of the set bits returned by @code{net_initdrivers}, or the @code{num} entry for one of the elements in a @code{NET_DRIVERNAME} array.@var{binding} determines the local binding for the channel. Pass@code{NULL} if you don't care. Otherwise, pass a string. The empty stringalways causes a default binding to be used; otherwise the string'smeaning depends upon the driver in use.@subsubheading Return valueThis function returns a pointer to the @code{NET_CHANNEL} struct it creates, or @code{NULL} on error.@subsubheading Compatibility with older versionsIn Libnet versions before 0.9.13 this function did not have the@code{binding} parameter, and there was another function,@code{net_openinputchannel}. To make that code work with the newAPI you need to change calls to these two functions:@table @asis@item net_openchannel (chan)Change to @code{net_openchannel (chan, NULL)}@item net_openinputchannel (chan)Change to @code{net_openchannel (chan, "")}@end table@subsubheading NotesThe meaning of the @code{binding} parameter may seem a bitmisty. As a general rule, if a channel is going to receivefirst-contact data from other computers, you must specifyits binding. If it's going to be used to send/receive data after initial contact has been established then its binding doesn't matter.As an analogy, let's consider a group of people who want tocommunicate through email. The people represent the computersin your game.First imagine that none of the people know any of theemail addresses. Obviously, nobody can communicate. This represents a situation where all channels were opened with @code{binding = NULL}.Now suppose A knows B's email address. Then A can communicate with B in both directions, because as soon as A sends B an email,B can look at the return address to discover A's address. Thisrepresents a situation where computer B initialised a channel with a specific binding. A's channel did not need a specific binding, since he made first contact, not B.Now for a more accurate analogy. Imagine each person has a wholedomain to themself, but nobody knows which users exist at each domain. So nobody can send messages; this is the first scenario again.In the second scenario, A knows that B has a user called "default". So A can send email to that user from any of hisown users. And then B can send email back to whichever of A's users have already sent email to B, from any of his [B's] users. Again, only one of them needed to have a channel of known binding. This represents the situation where B initialiseda channel with the empty string as @code{binding}. He got thedefault binding (i.e. "default" as username).So why don't we initialise all channels with the default binding? Well, only one channel could then exist per computer (actually per network type per computer). You can't have two users both called "default".Next consider the situation where B has two domains, one on net1 and one on net2, while A has only one, on net1, and C has only one, on net2. Assume that A and B are communicating andB and C are communicating; then B knows email addresses for A andC. Can A and C then communicate, if B tells them what each other's addresses are? No, because they're on different networks.In this situation, B might want to explicitly bind channels tonetworks net1 and net2, rather than letting the driver make a (possibly) bad choice. This is a reason why you might want tolet the user choose the binding. B is a gateway here, and this isa fairly unusual situation for a multiplayer game, but it canbe a useful feature. An example of B is a machine on a LAN (which runs Internet Protocol), with a modem connection to the Internet itself. A is out on the Internet and C is on the LAN. In fact, the machine on which I am typing this is in this situation.@c ----------------------------------------------------------------@node net_closechannel, net_assigntarget, net_openchannel, Channel Functions@subsection net_closechannel@findex net_closechannel@subsubheading Prototype@exampleint net_closechannel(NET_CHANNEL *channel);@end example@subsubheading PurposeCloses a previously opened channel. This will notnecessarily inform the remote machine; it will simplydiscard the channel record, after inviting the networkdriver responsible to tidy things up.@subsubheading Parameters@var{channel} is the channel to close.@subsubheading Return valueReturns 0 on success.@subsubheading Example@exampleNET_CHANNEL *chan = net_openchannel (driver, binding);net_closechannel (chan);@end example@c ----------------------------------------------------------------@node net_assigntarget, net_getlocaladdress, net_closechannel, Channel Functions@subsection net_assigntarget@findex net_assigntarget@subsubheading Prototype@exampleint net_assigntarget(NET_CHANNEL *channel, char *target);@end example@subsubheading PurposeSets the target of the given channel.@subsubheading Parameters@var{channel} is the channel whose target address needs changing. @var{target} is the new target address. The format of the target address depends upon the network type being used by the channel.@subsubheading Return valueZero on success, nonzero on error (i.e. address in wrongformat). A zero return does not indicate that the targetcan necessarily be reached.@subsubheading Example@exampleNET_CHANNEL *chan = net_openchannel (NET_DRIVER_WSOCK, NULL);net_assigntarget (chan, "127.0.0.1:12345");@end example@c ----------------------------------------------------------------@node net_getlocaladdress, net_send, net_assigntarget, Channel Functions@subsection net_getlocaladdress@findex net_getlocaladdress@subsubheading Prototype@examplechar *net_getlocaladdress(NET_CHANNEL *channel);@end example@subsubheading PurposeThis function is used to discover the local address of a channel.@subsubheading Parameters@var{channel} is the channel whose local address is wanted.@subsubheading Return valueThe address of @var{channel} is returned in the driver's normal address format.@subsubheading Notes@dfn{local address} means the address of the channel according to this computer. This might not be the address other computers should use; for example, a serial port driver would have no way of knowing what port the other computer should use. The Internet sockets drivers have a bit of trouble with this too, since a computer can have more than one IP address and it's not trivial to find out even one of these.Because of all this, it's probably best to tell the user this local address and let them figure out what the other computer should use.@subsubheading Example@exampleNET_CHANNEL *chan;chan = net_openchannel (driver, binding);printf ("Local address of channel: %s\n", net_getlocaladdress (chan));@end example@c ----------------------------------------------------------------@node net_send, net_receive, net_getlocaladdress, Channel Functions@subsection net_send@findex net_send@subsubheading Prototype@exampleint net_send(CHANNEL *channel,void *buffer,int size);@end example@subsubheading PurposeSends data down a channel.@subsubheading Parameters@var{channel} is the channel to send the data through. @var{buffer} points to the data to send. @var{size} is the size of the data in bytes.@subsubheading Return valueZero on success, non-zero on error.@subsubheading Example@xref{net_receive}.@c ----------------------------------------------------------------@node net_receive, net_query, net_send, Channel Functions@subsection net_receive@findex net_receive@subsubheading Prototype@exampleint net_receive(CHANNEL *channel,void *buffer,int maxsize,char *from);@end example@subsubheading PurposeReceives data from a channel.@subsubheading Parameters@var{channel} is the channel to receive from. @var{buffer} is a buffer to hold the data, of length @var{maxsize}. If @var{from} is not @code{NULL}, the address of the source ofthe data will be stored in the buffer it points to (which should be able to hold NET_MAX_ADDRESS_LENGTH characters).@subsubheading Return valueReturns the number of bytes received. 0 is valid; therewas no data to read. -1 indicates that an error occured.@subsubheading Example@exampleNET_CHANNEL *chan;char buffer1[32] = "Data to send";char buffer2[32] = "";int x;chan = net_openchannel (NET_DRIVER_WSOCK, "");net_assigntarget (chan, "127.0.0.1");net_send (chan, buffer1, strlen (buffer1) + 1);do @{ x = net_receive (chan, buffer2, 32, NULL);@} while (x == 0);if (x > 0) printf ("Received data: %s\n", buffer2);else printf ("Error receiving data.\n");@end example@c ----------------------------------------------------------------@node net_query, , net_receive, Channel Functions@subsection net_query@findex net_query@subsubheading Prototype@exampleint net_query(CHANNEL *channel);@end example@subsubheading PurposeThis function checks to see if there is data waiting to be read from the channel.@subsubheading Parameters@var{channel} is the channel to query.@subsubheading Return valueReturns nonzero if data is waiting, zero if not.@subsubheading Example@exampleif (net_query (chan)) get_data(chan);@end example@c ----------------------------------------------------------------@node Connection Functions, Driver List Functions, Channel Functions, Functions@section Connection Functions@cindex reliable communication, functions@cindex connection functions@cindex conn functions@cindex conn@cindex conn, functions to work with@cindex RDM@cindex important messages@cindex functions, connLibnet's channels are unreliable --- there's no guarantee that a packet will arrive at its destination, nor that packets won't get duplicated en route, nor that packets will arrive in the right order. If you bear those facts in mind, channels should be fine for most uses (in particular, cases where data is made redundant very quickly by new incoming data).Sometimes though you want to be able to send a packet and be sure that it will reach its destination. Libnet's second typeof communicator is the @dfn{connection}. A connection is a fixed link between two computers. You can't assign a new target. Packets sent along a connection are guaranteed to arrive precisely once, and in the correct order.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -