Initial repository 1.0.0
This commit is contained in:
commit
d8b1275884
1861 files changed
+66342
No files matched your search
@@ -0,0 +1,15 @@
|
||||
\relax
|
||||
\@writefile{toc}{\contentsline {chapter}{\numberline {1}Overview}{3}}
|
||||
\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\contentsline {chapter}{\numberline {2}Linux epoll Interactions}{5}}
|
||||
\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\contentsline {chapter}{\numberline {3}The Core Server}{7}}
|
||||
\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\contentsline {chapter}{\numberline {4}Sample Server Example}{9}}
|
||||
\@writefile{lof}{\addvspace {10\p@ }}
|
||||
\@writefile{lot}{\addvspace {10\p@ }}
|
||||
\@writefile{toc}{\contentsline {section}{\numberline {4.1}The Server}{9}}
|
||||
\@writefile{toc}{\contentsline {section}{\numberline {4.2}The Session}{11}}
|
||||
@@ -0,0 +1,200 @@
|
||||
This is pdfTeX, Version 3.14159265-2.6-1.40.18 (TeX Live 2017/Debian) (preloaded format=pdflatex 2018.5.16) 18 MAY 2018 02:53
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
**"BMASockets Programmer's Guide.tex"
|
||||
(./BMASockets Programmer's Guide.tex
|
||||
LaTeX2e <2017-04-15>
|
||||
Babel <3.18> and hyphenation patterns for 5 language(s) loaded.
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/book.cls
|
||||
Document Class: book 2014/09/29 v1.4h Standard LaTeX document class
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/bk10.clo
|
||||
File: bk10.clo 2014/09/29 v1.4h Standard LaTeX file (size option)
|
||||
)
|
||||
\c@part=\count79
|
||||
\c@chapter=\count80
|
||||
\c@section=\count81
|
||||
\c@subsection=\count82
|
||||
\c@subsubsection=\count83
|
||||
\c@paragraph=\count84
|
||||
\c@subparagraph=\count85
|
||||
\c@figure=\count86
|
||||
\c@table=\count87
|
||||
\abovecaptionskip=\skip41
|
||||
\belowcaptionskip=\skip42
|
||||
\bibindent=\dimen102
|
||||
)
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty
|
||||
Package: xcolor 2016/05/11 v2.12 LaTeX color extensions (UK)
|
||||
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/graphics-cfg/color.cfg
|
||||
File: color.cfg 2016/01/02 v1.6 sample color configuration
|
||||
)
|
||||
Package xcolor Info: Driver file: pdftex.def on input line 225.
|
||||
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/graphics-def/pdftex.def
|
||||
File: pdftex.def 2018/01/08 v1.0l Graphics/color driver for pdftex
|
||||
)
|
||||
Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1348.
|
||||
Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1352.
|
||||
Package xcolor Info: Model `RGB' extended on input line 1364.
|
||||
Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1366.
|
||||
Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1367.
|
||||
Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1368.
|
||||
Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1369.
|
||||
Package xcolor Info: Model `Gray' substituted by `gray' on input line 1370.
|
||||
Package xcolor Info: Model `wave' substituted by `hsb' on input line 1371.
|
||||
)
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/listings/listings.sty
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty
|
||||
Package: keyval 2014/10/28 v1.15 key=value parser (DPC)
|
||||
\KV@toks@=\toks14
|
||||
)
|
||||
\lst@mode=\count88
|
||||
\lst@gtempboxa=\box26
|
||||
\lst@token=\toks15
|
||||
\lst@length=\count89
|
||||
\lst@currlwidth=\dimen103
|
||||
\lst@column=\count90
|
||||
\lst@pos=\count91
|
||||
\lst@lostspace=\dimen104
|
||||
\lst@width=\dimen105
|
||||
\lst@newlines=\count92
|
||||
\lst@lineno=\count93
|
||||
\lst@maxwidth=\dimen106
|
||||
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty
|
||||
File: lstmisc.sty 2015/06/04 1.6 (Carsten Heinz)
|
||||
\c@lstnumber=\count94
|
||||
\lst@skipnumbers=\count95
|
||||
\lst@framebox=\box27
|
||||
)
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/listings/listings.cfg
|
||||
File: listings.cfg 2015/06/04 1.6 listings configuration
|
||||
))
|
||||
Package: listings 2015/06/04 1.6 (Carsten Heinz)
|
||||
|
||||
(./BMASockets Programmer's Guide.aux)
|
||||
\openout1 = `"BMASockets Programmer's Guide.aux"'.
|
||||
|
||||
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 30.
|
||||
LaTeX Font Info: ... okay on input line 30.
|
||||
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 30.
|
||||
LaTeX Font Info: ... okay on input line 30.
|
||||
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 30.
|
||||
LaTeX Font Info: ... okay on input line 30.
|
||||
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 30.
|
||||
LaTeX Font Info: ... okay on input line 30.
|
||||
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 30.
|
||||
LaTeX Font Info: ... okay on input line 30.
|
||||
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 30.
|
||||
LaTeX Font Info: ... okay on input line 30.
|
||||
|
||||
(/usr/share/texlive/texmf-dist/tex/context/base/mkii/supp-pdf.mkii
|
||||
[Loading MPS to PDF converter (version 2006.09.02).]
|
||||
\scratchcounter=\count96
|
||||
\scratchdimen=\dimen107
|
||||
\scratchbox=\box28
|
||||
\nofMPsegments=\count97
|
||||
\nofMParguments=\count98
|
||||
\everyMPshowfont=\toks16
|
||||
\MPscratchCnt=\count99
|
||||
\MPscratchDim=\dimen108
|
||||
\MPnumerator=\count100
|
||||
\makeMPintoPDFobject=\count101
|
||||
\everyMPtoPDFconversion=\toks17
|
||||
)
|
||||
\c@lstlisting=\count102
|
||||
(./BMASockets Programmer's Guide.toc
|
||||
LaTeX Font Info: External font `cmex10' loaded for size
|
||||
(Font) <7> on input line 5.
|
||||
LaTeX Font Info: External font `cmex10' loaded for size
|
||||
(Font) <5> on input line 5.
|
||||
)
|
||||
\tf@toc=\write3
|
||||
\openout3 = `"BMASockets Programmer's Guide.toc"'.
|
||||
|
||||
[1
|
||||
|
||||
|
||||
{/var/lib/texmf/fonts/map/pdftex/updmap/pdftex.map}] [2
|
||||
|
||||
]
|
||||
Chapter 1.
|
||||
[3] [4
|
||||
|
||||
]
|
||||
Chapter 2.
|
||||
[5] [6
|
||||
|
||||
]
|
||||
Chapter 3.
|
||||
|
||||
Overfull \hbox (1.13943pt too wide) in paragraph at lines 108--112
|
||||
[]\OT1/cmr/m/n/10 The ex-tended BMASes-sion ob-ject can over-ride the on-DataRe
|
||||
-ceived() method
|
||||
[]
|
||||
|
||||
[7] [8
|
||||
|
||||
]
|
||||
Chapter 4.
|
||||
|
||||
Overfull \hbox (0.16724pt too wide) in paragraph at lines 121--122
|
||||
[]\OT1/cmr/m/n/10 Additionally, this server ex-am-ple pro-vides a con-sole that
|
||||
is ac-ces-si-ble through
|
||||
[]
|
||||
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/listings/lstlang1.sty
|
||||
File: lstlang1.sty 2015/06/04 1.6 listings language file
|
||||
)
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty
|
||||
File: lstmisc.sty 2015/06/04 1.6 (Carsten Heinz)
|
||||
) [9]
|
||||
LaTeX Font Info: Try loading font information for OMS+cmr on input line 140.
|
||||
|
||||
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/omscmr.fd
|
||||
File: omscmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions
|
||||
)
|
||||
LaTeX Font Info: Font shape `OMS/cmr/m/n' in size <8> not available
|
||||
(Font) Font shape `OMS/cmsy/m/n' tried instead on input line 140.
|
||||
LaTeX Font Info: Try loading font information for OML+cmr on input line 150.
|
||||
|
||||
|
||||
(/usr/share/texlive/texmf-dist/tex/latex/base/omlcmr.fd
|
||||
File: omlcmr.fd 2014/09/29 v2.5h Standard LaTeX font definitions
|
||||
)
|
||||
LaTeX Font Info: Font shape `OML/cmr/m/n' in size <8> not available
|
||||
(Font) Font shape `OML/cmm/m/it' tried instead on input line 150.
|
||||
LaTeX Font Info: External font `cmex10' loaded for size
|
||||
(Font) <8> on input line 190.
|
||||
LaTeX Font Info: External font `cmex10' loaded for size
|
||||
(Font) <6> on input line 190.
|
||||
[10] [11] [12]
|
||||
(./BMASockets Programmer's Guide.aux) )
|
||||
Here is how much of TeX's memory you used:
|
||||
2684 strings out of 494880
|
||||
36203 string characters out of 6179601
|
||||
236674 words of memory out of 5000000
|
||||
6032 multiletter control sequences out of 15000+600000
|
||||
8287 words of font info for 29 fonts, out of 8000000 for 9000
|
||||
36 hyphenation exceptions out of 8191
|
||||
30i,6n,58p,392b,1622s stack positions out of 5000i,500n,10000p,200000b,80000s
|
||||
</usr/share/texlive/texmf-dist/fonts/typ
|
||||
e1/public/amsfonts/cm/cmbx10.pfb></usr/share/texlive/texmf-dist/fonts/type1/pub
|
||||
lic/amsfonts/cm/cmbx12.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/am
|
||||
sfonts/cm/cmmi8.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/
|
||||
cm/cmr10.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr5
|
||||
.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb></u
|
||||
sr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsl10.pfb></usr/sha
|
||||
re/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmsy8.pfb></usr/share/texl
|
||||
ive/texmf-dist/fonts/type1/public/amsfonts/cm/cmti10.pfb>
|
||||
Output written on "BMASockets Programmer's Guide.pdf" (12 pages, 129850 bytes).
|
||||
|
||||
PDF statistics:
|
||||
79 PDF objects out of 1000 (max. 8388607)
|
||||
55 compressed objects within 1 object stream
|
||||
0 named destinations out of 1000 (max. 500000)
|
||||
1 words of extra memory for PDF output out of 10000 (max. 10000000)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,275 @@
|
||||
\documentclass[10pt]{book}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{listings}
|
||||
|
||||
\definecolor{mGreen}{rgb}{0,0.6,0}
|
||||
\definecolor{mGray}{rgb}{0.5,0.5,0.5}
|
||||
\definecolor{mPurple}{rgb}{0.58,0,0.82}
|
||||
\definecolor{backgroundColour}{rgb}{0.95,0.95,0.92}
|
||||
|
||||
\lstdefinestyle{CStyle}{
|
||||
backgroundcolor=\color{backgroundColour},
|
||||
commentstyle=\color{mGreen},
|
||||
keywordstyle=\color{magenta},
|
||||
numberstyle=\tiny\color{mGray},
|
||||
stringstyle=\color{mPurple},
|
||||
basicstyle=\footnotesize,
|
||||
breakatwhitespace=false,
|
||||
breaklines=true,
|
||||
captionpos=b,
|
||||
keepspaces=true,
|
||||
numbers=left,
|
||||
numbersep=5pt,
|
||||
showspaces=false,
|
||||
showstringspaces=false,
|
||||
showtabs=false,
|
||||
tabsize=2,
|
||||
language=C
|
||||
}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\tableofcontents
|
||||
|
||||
\chapter{Overview}
|
||||
|
||||
Welcome to BMASockets Core Server. The server core was developed to
|
||||
provide a quick path to developing your server requirements on a high
|
||||
performance Linux platform network. The design can be used to develop
|
||||
customing gaming platforms or you can use any of the existing protocol
|
||||
session handlers to implement your own compact high performance server
|
||||
using existing known protocols.
|
||||
|
||||
The BMASockets Core Server provides existing handlers for the
|
||||
following protocols:
|
||||
|
||||
\begin{enumerate}
|
||||
\item HTTP and HTTPS
|
||||
\item SIP and SIPS
|
||||
\item HTTP streaming server
|
||||
\item HTTP Web Sockets handler
|
||||
\end{enumerate}
|
||||
|
||||
The focus of the design is to extend the capabilities of two core
|
||||
objects to create the interface to your own implementations.
|
||||
|
||||
\chapter{Linux epoll Interactions}
|
||||
|
||||
Linux provides an set of system calls to open a socket that is used to
|
||||
manage the networking requests for multiple sockets from a single
|
||||
process. You can find plenty of materials on the internet on epoll and
|
||||
how this function works. The Core Server is designed around the
|
||||
concept of the socket (BMASocket) and the handling of accepting
|
||||
connections on a binding socket and managing the individual client
|
||||
sockets that are \emph{accepted}.
|
||||
|
||||
TCP and UDP are both supported by the Core Server. The differences in
|
||||
managing these socket types is abstracted through the use of the
|
||||
sessions object (BMASession). This abstract class cannot be
|
||||
instantiated but is used instead to extend into a customizable session
|
||||
object that will be used to manage the protocol for the connected
|
||||
session. At the session level there is no difference between the
|
||||
underlying socket type, whether it be UDP or TCP.
|
||||
|
||||
The TCP side of the fence incorporates the connection oriented design
|
||||
to provide the sessions to the higher levels. Each client represents a
|
||||
socket that has connected through the \emph{bind} and \emph{accept}
|
||||
system call method. Conversing with a client in a TCP session returns
|
||||
the appropriate data through that socket connection.
|
||||
|
||||
The UDP side of the fence incorporates session objects that are based
|
||||
upon connectionless packets sent to a single receiving socket. The UDP
|
||||
server (BMAUDPServerSocket) maintains a list of sessions which are
|
||||
managed according the sending address of the packets received. Each remote
|
||||
address represents a different client and interactions back to the
|
||||
session are sent through the single socket to the corresponding remote
|
||||
address. This provides a seamless session to the higher level
|
||||
activities of the server.
|
||||
|
||||
The interface provided through the session appears the same regardless
|
||||
of the socket type. This affords the developer the opportunity to
|
||||
write UDP or TCP socket handlers with no knowledge of the those
|
||||
protocols. Building a game server would be the same for either type
|
||||
and both types could be enabled simultaneously.
|
||||
|
||||
\chapter{The Core Server}
|
||||
|
||||
In order to provide flexibility to the Core Server several design
|
||||
factors have been put in place. Creating a new server that handles a
|
||||
custom protocol requires the extension of only two objects. These are
|
||||
the BMATCPServerSocket or BMAUDPServerSocket, depending on the type
|
||||
desired, and the BMASession object.
|
||||
|
||||
When extending the BMATCPServerSocket all that is needed is to
|
||||
override the getSocketAccept() method to return an extended BMASession
|
||||
object. This basically tells the server to spawn a new session of a
|
||||
particular type for every new connection to the bound TCP port.
|
||||
|
||||
The extended BMASession object can override the onDataReceived()
|
||||
method to handle the incoming requests for the socket. An entire
|
||||
application structure could be built upon this mechanism to handle
|
||||
complex protocols with the client.
|
||||
|
||||
\chapter{Sample Server Example}
|
||||
|
||||
This chapter specifies the approach to extending and creating a customized server. This example is focusing on a server used in gaming environments. The gaming clients connect to the server to interact with other clients.
|
||||
|
||||
The BMA Server Core can provide all the features needed of a multiport high demand server. The implementation of epoll combined with the ability to manage job control load through the use of multiple threads provides a robust request handling environment for all socket based architectures.
|
||||
|
||||
As the BMAEPoll object is started it will spawn the specified number of threads which will in turn begin the socket handling functions necessary to manage all network requests in the program. The main program itself is not used but must not be allowed to return or end so it can be used to handle other non sockets related processing in the application.
|
||||
|
||||
Additionally, this server example provides a console that is accessible through a Telnet style server and does not currently incorporate any encryption (TLS) or login authentication. This will be changing in the future.
|
||||
|
||||
\section{The Server}
|
||||
|
||||
The server provides a few interesting features that may not be readily apparent when reading through the documentation.
|
||||
|
||||
Since each BMATCPServerSocket also inherits from BMACommand the server can override a routine to output data relivant to the type of server you are creating.
|
||||
|
||||
When creating the server you are asked to provide a command name as a parameter. The inheriting server object can then obtain a list of connected clients from a console object by typing this name in on a command line.
|
||||
|
||||
\begin{lstlisting}[style=CStyle]
|
||||
#ifndef BMAConsoleServer_h__
|
||||
#define BMAConsoleServer_h__
|
||||
|
||||
#include "includes"
|
||||
#include "BMATCPServerSocket.h"
|
||||
#include "BMACommand.h"
|
||||
class BMATCPSocket;
|
||||
|
||||
class BMAConsoleServer : public BMATCPServerSocket {
|
||||
|
||||
public:
|
||||
BMAConsoleServer(BMAEPoll &ePoll, std::string url, short int port);
|
||||
~BMAConsoleServer();
|
||||
|
||||
BMASession * getSocketAccept();
|
||||
|
||||
void registerCommand(BMACommand &command);
|
||||
|
||||
int processCommand(BMASession *session) override; ///<Output the consoles array to the console.
|
||||
|
||||
std::vector<BMACommand *> commands;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{lstlisting}[style=CStyle]
|
||||
#include "BMAEPoll.h"
|
||||
#include "BMAConsoleServer.h"
|
||||
#include "BMAConsoleSession.h"
|
||||
#include "BMACommand.h"
|
||||
|
||||
BMAConsoleServer::BMAConsoleServer(BMAEPoll &ePoll, std::string url, short int port)
|
||||
: BMATCPServerSocket(ePoll, url, port, "consoles") {
|
||||
// ePoll.log.registerConsole(*this);
|
||||
// ePoll.log.write(0) << "BMAConsole initializing..." << endl;
|
||||
}
|
||||
|
||||
BMAConsoleServer::~BMAConsoleServer() {
|
||||
|
||||
}
|
||||
|
||||
BMASession * BMAConsoleServer::getSocketAccept() {
|
||||
return new BMAConsoleSession(ePoll, *this);
|
||||
}
|
||||
|
||||
void BMAConsoleServer::registerCommand(BMACommand &command) {
|
||||
commands.push_back(&command);
|
||||
}
|
||||
|
||||
int BMAConsoleServer::processCommand(BMASession *session) {
|
||||
|
||||
std::stringstream out;
|
||||
int sequence = 0;
|
||||
|
||||
for(BMASession *session : sessions) {
|
||||
out << "|" << ++sequence;
|
||||
out << "|" << session->getClientAddressAndPort();
|
||||
out << "|" << std::endl;
|
||||
}
|
||||
|
||||
session->write((char *)out.str().c_str(), out.str().size());
|
||||
|
||||
return 0;
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\section{The Session}
|
||||
|
||||
\begin{lstlisting}[style=CStyle]
|
||||
#include "includes"
|
||||
#include "BMAEPoll.h"
|
||||
#include "BMAMP3File.h"
|
||||
#include "BMAConsoleServer.h"
|
||||
#include "BMATCPServerSocket.h"
|
||||
#include "BMAStreamServer.h"
|
||||
#include "BMAHTTPServer.h"
|
||||
#include "BMASIPServer.h"
|
||||
#include "BMAHTTPRequestHandler.h"
|
||||
#include "BMAMP3StreamContentProvider.h"
|
||||
#include "BMATimer.h"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
std::string ipAddress = "0.0.0.0";
|
||||
|
||||
BMAEPoll ePoll;
|
||||
ePoll.start(4, 1000);
|
||||
|
||||
//----------------------
|
||||
// Testing TCP server.
|
||||
//----------------------
|
||||
|
||||
BMATCPServerSocket tcpServer(ePoll, ipAddress, 1028, "users");
|
||||
|
||||
//------------------------
|
||||
// MP3 Streaming Server
|
||||
//------------------------
|
||||
|
||||
BMAStreamServer stream(ePoll, ipAddress, 1032, "listeners");
|
||||
BMAMP3File tester(stream, "../extravaganza.mp3");
|
||||
|
||||
//--------------
|
||||
// HTTP Server
|
||||
//--------------
|
||||
|
||||
BMAHTTPServer http(ePoll, ipAddress, 1080, "http");
|
||||
BMAHTTPRequestHandler handler1(http, "/");
|
||||
|
||||
//-------------
|
||||
// SIP Server
|
||||
//-------------
|
||||
|
||||
BMASIPServer sip(ePoll, ipAddress, 5061, "sip");
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Console controller so the program can be monitored through
|
||||
// a telnet session. BMATCPServerSocket can be registered as
|
||||
// a command and will report its status when the command is
|
||||
// entered on the console.
|
||||
//-------------------------------------------------------------
|
||||
|
||||
BMAConsoleServer console(ePoll, ipAddress, 1027);
|
||||
console.registerCommand(ePoll);
|
||||
console.registerCommand(console);
|
||||
console.registerCommand(http);
|
||||
console.registerCommand(sip);
|
||||
console.registerCommand(stream);
|
||||
|
||||
ePoll.start(4, 1000);
|
||||
|
||||
while(true)
|
||||
sleep(300);
|
||||
|
||||
ePoll.stop();
|
||||
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
\end{document}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
\contentsline {chapter}{\numberline {1}Overview}{3}
|
||||
\contentsline {chapter}{\numberline {2}Linux epoll Interactions}{5}
|
||||
\contentsline {chapter}{\numberline {3}The Core Server}{7}
|
||||
\contentsline {chapter}{\numberline {4}Sample Server Example}{9}
|
||||
\contentsline {section}{\numberline {4.1}The Server}{9}
|
||||
\contentsline {section}{\numberline {4.2}The Session}{11}
|
||||
Reference in new issue
Block a user