By Program (CODE)
/Kyle
It is estimated that everyone misses the Win32 Socket API or * nix socket
API, if you start Symbian programming. Win32 has a bunch of socket operation interfaces and various modes. Select model, asynchronous, complete port, MFC Encapsulation
Two socket classes. After using these things for a long time, I forgot about other methods. * Epoll can be used in Nix. In essence, it is also an asynchronous control flip. Below is
The socket code example of Symbian is fast in one click, where Chinese is occasionally added, and its code indent style is modified.
/* Copyright (c) 2001, Nokia. All Rights Reserved */
# Ifndef _ socketsengine_h __
# DEFINE _ socketsengine_h __
# Include <in_sock.h>
# Include "timeoutnotifier. H"
# Include "enginenotifier. H"
# Include "sockets. HRH"
Class csocketsreader;
Class csocketswriter;
Class ctimeouttimer;
Class muinotifier;
// Socket requires an engine class to support each interface. The following is the engine interface declaration.
// Because socketengine requires callback, It inherits cactive,
// The mtimeoutnotifier interface is also implemented because a timeout event needs to be notified,
// And the interface menginenotifier required by the code that wants to know what happened to the engine
/*!
@ Class csocketsengine
@ Discussion this class is the main engine part of the sockets application.
It establishes a TCP connection using its server name and port number (discovery a DNS Lookup
Operation first, if appropriate ).
It creates instances of separate active objects to perform reading from, and writing to, the socket.
*/
Class csocketsengine: Public cactive, public mtimeoutnotifier, public menginenotifier
{
Public: // New Methods
/*!
@ Function newl
@ Discussion create a csocketsengine object
@ Param aconsole console to use for UI output
@ Result a pointer to the created instance of csocketsengine
*/
Static csocketsengine * newl (muinotifier & aconsole );
/*!
@ Function newlc
@ Discussion create a csocketsengine object
@ Param aconsole console to use for UI output
@ Result a pointer to the created instance of csocketsengine
*/
Static csocketsengine * newlc (muinotifier & aconsole );
/*!
@ Function ~ Csocketsengine
@ Discussion destroy the object and release all memory objects
*/
~ Csocketsengine ();
/*!
@ Function connectl
@ Discussion initiate connection of socket, using iservername and iport
*/
Void connectl ();
/*!
@ Function disconnect
@ Discussion disconnect socket
*/
Void disconnect ();
/*!
@ Function writel
@ Discussion write data to socket
@ Param aData data to be written
*/
Void writel (const tdesc8 & aData );
// Trigger the active object socketreader instead of reading socket data,
// The operations that can actually read data are in the runl of socketreader.
/*!
@ Function read
@ Discussion initiate read of data from socket
*/
Void read ();
/*!
@ Function setservername
@ Discussion set name of server to connect
@ Param aname new server name
*/
Void setservername (const tdesc & aname );
/*!
@ Function servername
@ Discussion get server name
@ Result name of server
*/
Const tdesc & servername () const;
/*!
@ Function setport
@ Discussion set port number to connect
@ Param aport New Port Number
*/
Void setport (tint aport );
/*!
@ Function Port
@ Discussion get port number
@ Result port number
*/
Tint port () const;
/*!
@ Function connected
@ Discussion is socket fully connected?
@ Result true if socket is connected
*/
Tbool connected () const;
Public: // from mtimeoutnotifier
/*!
@ Function timerexpired
@ Discussion the function to be called when a timeout occurs
*/
Void timerexpired ();
Public: // from menginenotifier
/*!
@ Function reporterror
@ Discussion report a communication error
@ Param aerrortype Error Type
@ Param aerrorcode associated error code
*/
Void reporterror (menginenotifier: terrortype aerrortype, tint aerrorcode );
/*!
@ Function responsereceived
@ Discussion data has been encrypted ed on the socket and read into a buffer
@ Param abuffer the Data Buffer
*/
Void responsereceived (const tdesc8 & abuffer );
Protected: // from cactive
/*!
@ Function docancel
@ Discussion cancel any outstanding operation
*/
Void docancel ();
/*!
@ Function runl
@ Discussion called when Operation complete
*/
Void runl ();
PRIVATE: // New Methods
/*!
@ Function csocketsengine
@ Discussion perform the first phase of two phase construction
@ Param aconsole the console to use for UI output
*/
Csocketsengine (muinotifier & aconsole );
/*!
@ Function constructl
@ Discussion perform the second phase construction of a csocketsengine
*/
Void constructl ();
/*!
@ Function connectl
@ Discussion initiate a connect operation on a socket
@ Param aaddr the IP address to connect
*/
Void connectl (tuint32 aaddr );
/*!
@ Enum tsocketsenginestate
@ Discussion tracks the state of this object through the connection process
@ Value enotconnected the initial (idle) State
@ Value econnecting a CONNECT request is pending with the socket server
@ Value econnected a connection has been established
@ Value elookingup a DNS lookup request is pending with the socket server
*/
Enum tsocketsenginestate
{
Enotconnected,
Econnecting,
Econnected,
Elookingup
};
/*!
@ Function changestatus
@ Discussion handle a change in this object's status
@ Param anewstatus new status
*/
Void changestatus (tsocketsenginestate anewstatus );
/*!
@ Function print
@ Discussion display text on the console
@ Param ades text to display
*/
Void print (const tdesc & ades );
PRIVATE: // member variables
/*! @ Const the maximum time allowed for a lookup or connect requests to complete */
Static const tint ktimeout;
/*! @ Const the initial port number displayed to the user */
Static const tint kdefaportportnumber;
/*! @ Var this object's current status */
Tsocketsenginestate ienginestatus;
/*! @ Var console for displaying text etc */
Muinotifier & iconsole;
/*! @ Var the actual socket */
Rsocket isocket;
/*! @ Var active object to control reads from the socket */
Csocketsreader * isocketsreader;
/*! @ Var active object to control writes to the socket */
Csocketswriter * isocketswriter;
/*! @ Var the socket server */
Rsocketserv isocketserv;
/*! @ Var DNS name resolver */
Fig;
/*! @ Var the result from the Name Resolver */
Tnameentry inameentry;
/*! @ Var the anme record found by the resolver */
Tnamerecord inamerecord;
/*! @ Var timer active object */
Ctimeouttimer * itimer;
/*! @ Var the address to be used in the connection */
Tinetaddr iaddress;
/*! @ Var port number to connect */
Tint iport;
/*! @ Var server name to connect */
Tbuf <kmaxservernamelength> iservername;
};
# Endif/_ socketsengine_h __
From the code above, we can see that socketengine fully reflects the design style and tendency of the Symbian System in interface design.
1. Cut each task into various active objects.
2. The active object usually needs to keep its own state machine and other information to ensure that it knows what it is doing when runl is called.
3.
Use and use of m interface classes. Try to use an interface in combination, unless the current class needs to provide interfaces to other modules, the interface is inherited. For example
Socketwriter and socketreader are combined because the external module does not need to understand reader and writer. What the external interface wants to know is
Menginenotifier
The declared interface. Therefore, socketengine implements this interface, but it is actually implemented by socketreader and socketwriter at runl or other
.
4. Active Object
It is actually a "Callback" function, but it is only oo. In terms of use and design, there are some violations of conventional human thinking. For example, to establish a socket connection
Only the data fed back by scheduler can be analyzed. It is not a simple blocking method. This indicates that this model is a fully oo asynchronous model. We hope to reduce all computing overhead. Set
Polling and other operations are internalized in the kernel, and user code is not required for management. The result is that the user code model is tightly coupled in the active mode of Symbian.
Object, the loss of choice, and violation of intuition. Haha ~