Symbian OS Communications (779884), страница 39
Текст из файла (страница 39)
It is controlled by aseries of timeouts set for the connection in CommsDat.There is one timer for each connection that measures how long aconnection has been idle, and depending on the current usage modeof the connection can be in one of three states. The timeout values foreach of the three states are configured in CommsDat and one or more ofthem may be visible to the user – how they are exposed depends on theUI platform. The application does not need to be concerned with theirvalues as long as it is able to handle the connection being terminated(and since you need to cope with the case where the user terminates theconnection manually in your application, this case is not very different).The three different modes for the timer are based upon:1.When no user data has been sent for a given time.
On some UIplatforms this time interval is configurable by the user, potentially onlyfor some bearers, and the value usually differs between bearers. Forexample, a GPRS connection could be ‘always on’ without incurringany extra cost to the user, so would typically not have this timeout set;but a circuit-switched data call may be charged per-minute so couldbe terminated after five minutes of inactivity. On both S60 and UIQ,the timer is only exposed in the UI for circuit switched calls – othertechnologies have an infinite setting for this timer mode. This timermode is called LastSocketActivityTimeout in bearer tables inCommsDat.2.When there are no open sockets or host resolvers using the network connection.
This time interval is usually specified by the phonemanufacturer, and not exposed in the UI. It is called LastSocketClosedTimeout in the bearer tables in CommsDat.3.When there are no open RConnection objects using the connection. RConnection::Close() allows an application to indicatethat it no longer needs to use a network connection.
This should beused in preference to Stop(), for the reasons indicated previously.Each connection keeps a reference count of applications (actuallyRConnections) that are using that connection, and once this number reaches zero the timer switches to this mode. In the bearer tablesin CommsDat it is called LastSessionClosedTimeout.Note that calling RConnection::Close() also closes the RConnection’s handle to the socket server, and hence all the RSocket/USING THE NETWORK CONNECTION175RHostResolver objects that have been associated with that RConnection should be closed first.
Also note that this RConnection cannot beused again until you have called Open() on it.Note that in the case of (1) and (2), the application will still have a validRConnection, which can be used to receive progress notifications, andalso restart the connection if necessary.Applications affect the lifetime of a network connection by the typeof activity they perform or the objects they keep open – sockets, hostresolvers or connections. In addition, the behavior of a connectiondepends on the values set for the different idle timer modes in CommsDat.If you wish to keep a connection open, it may be necessary to implementsome form of keep-alive mechanism, depending on the values of thevarious timer modes and the network usage profile of your application.However, you should carefully consider the impact on both powerconsumption of the device and the potential to increase costs for the user.Bearer-initiated disconnectionsA connection to a mobile network may be terminated for a variety ofreasons which are not related to the applications using it.
For example, aGPRS network can initiate a disconnection from the network side due tolack of resources, network errors, or idle timeouts in the network; or thedevice may go out of range of the network. These are also common errorsfor other wireless bearers such as Bluetooth or WLAN.
Applications needto be designed to cope with this and handle the errors cleanly, e.g. byretrying the connection a finite number of times, or by prompting the userto retry later. The application must not repeatedly attempt to restart theconnection ad infinitum because that will quickly drain the battery of thedevice.Some errors are fatal whilst others are not, so applications should beable to determine when a retry mechanism has a chance of succeedingand when to just notify the user about the problem – typically errors abouttransient failures such as KErrNotReady should result in a limited number of retries, whereas permanent errors, such as KErrAccessDeniedshould result in an immediate user notification. This can be difficult insome circumstances, as the application isn’t always aware of which beareris being used (WCDMA, WLAN, etc.) and the errors may differ dependingon the bearer. It is possible to retrieve the last error that occurred on aconnection using RConnection::LastProgressError().6.4 Using the Network ConnectionOnce the application has a handle to an active network connection, it cansend and receive IP data.
The first thing it might want to do is to resolve176IP AND RELATED TECHNOLOGIESa domain name into an IP address. Before domain name resolution isdiscussed, internet addressing on Symbian OS needs some explanation.6.4.1 Internet AddressesIP addresses on Symbian OS are represented by the TInetAddr class.This is a derivation of the generic TSockAddr class already discussed inChapter 3. A TInetAddr stores both the IP address and the TCP/UDPport number to be used for the socket. Symbian OS supports both IPv4and IPv6 addresses, defined in in_sock.h.
The address family can bedetermined using the Family() method of the underlying TSockAddrclass. This will be KAfInet for an IPv4 address, and KAfInet6 for anIPv6 address:if( addr.Family() == KAfInet){// IPv4 addressing}else if (addr.Family() == KAfInet6){// IPv6 addressing}Addresses returned from the networking subsystem are usually inKAfInet6 format so care must be taken by the application if it intends toaccess the data in an address (rather than just passing it from RHostResolver::GetByName() to RSocket::Connect()) to handle theseusing the correct class as described below.
Currently, many addresses,although returned in IPv6 format, are actually IPv4 address in IPv4mapped format inside the IPv6 address.IPv4 addressesIPv4 addresses are stored as a 32-bit integer. However, they can be handled by the application in a number of different formats and conversionmethods exist to translate between them:• In ‘dotted quad’ notation inside a descriptor, for example‘‘192.168.1.1’’. In this case the Input() method is used to convertfrom the descriptor to the TInetAddr:_LIT(KInetAddr, "192.168.1.1"));TInetAddr addr;addr.Input(KInetAddr);• As a 32-bit integer.• As four separate 8-bit integers, each representing part of the address.USING THE NETWORK CONNECTION177The INET_ADDR macro makes these last two formats easy to use, andthe SetAddress() method can be used:const TUint32 KInetAddr = INET_ADDR(192,168,1,1);addr.SetAddress(KInetAddr);The address can also be created using the constructor if the portnumber is also known:const TUint32 KInetAddr = INET_ADDR(192,168,1,1);const TInt KPortNum = 8080;TInetAddr addr(KInetAddr, KPortNum);IPv6 addressesIPv6 addresses are handled in much the same way as IPv4 addresses, butbecause they are 128 bits long, they are stored inside a TSockAddr asa TIp6Addr object.
TIp6Addr can also store IPv4 addresses. Socketsrequire a TSockAddr-derived object so when using IP addresses directly,rather than obtaining them from the DNS, the TInetAddr must becreated using the TIp6Addr in the same way as the IPv4 address iscreated using the IPv4 specific overloads.All addresses are handled in the native byte order, so no byte-orderconversion functions are necessary.Useful constantsThere are also several commonly used IP addresses predefined in Symbian OS that applications may find useful such as KInetAddrAll andKInetAddrBroadcast (both 255.255.255.255) and KInetAddrLoop(127.0.0.1).
Others are defined in in_sock.h.6.4.2 Domain Name ResolutionDomain name resolution is carried out using the RHostResolver API.This has already been discussed in Chapter 3 but is discussed specificallyin the context of DNS here. DNS is used to resolve an internet domainname into an IP address via a DNS server, as defined in RFC1034 andshown in Figure 6.5. Applications do not need to know the specificsof how this works, but they should be aware of the configuration andbehavior of the DNS implementation on Symbian OS.Each network interface is configured with the IP address of one or moreDNS servers, and in most cases this is provisioned dynamically duringthe connection process.
Alternately, it can be configured statically as partof the appropriate record in a service table in CommsDat. To ensurethat the DNS query is sent to the correct DNS server, an RConnectionmust be associated with the RHostResolver when it is opened. Legacyapplications, or applications using stdlib or PIPS sockets, and hence178IP AND RELATED TECHNOLOGIESApplicationCacheDNS clientDNS serverQueryRecordsResponses (AA, AAAA, PTR, etc.)Figure 6.5DNS architecturenot using RConnection will send the DNS queries over the implicitconnection, which will create a network connection if there is not asuitable one active. Once a valid DNS response is received, it is cacheduntil the lifetime of the reponse is reached, the device is shutdown, or thecache is cleared.RHostResolver iHr; // typically class members of an active objectTNameEntry iEntry;..._LIT8(KWwwSymbianCom, "www.symbian.com");User::LeaveIfError(iHr.Open(iSockServ, KAfInet, KProtocolInetUdp, iConn);hr.GetByName(KWwwSymbianCom, iEntry, iStatus));SetActive();Responses are stored in the TNameEntry.