Symbian OS Communications (779884), страница 8
Текст из файла (страница 8)
As a program needs to understand the details ofhow to use a protocol before it makes use of it, these are rarely used.3.1.4 RSocket and FriendsThe Symbian OS sockets API is provided by the RSocket class, foundin <es_sock.h>. The methods on this class break down into varioussections:1.Creating a new socket (and setting it up for use).2.Connecting to a service.3.Receiving connections from a peer.4.Sending data to a peer.5.Receiving data from a peer.6.Control functions: options and ioctls.7.Miscellaneous: naming, transferring and information.We’ll look at each of these areas in turn below, but first it’s importantto understand the different types of sockets and protocols understood bySymbian OS.Types of socketsWhile the sockets API provides a consistent syntax for using variousprotocols, the semantics of the APIs are partially dependent on the specificprotocol. Different protocols provide different services, guarantees andoptions, and this is reflected in the behavior of the sockets APIs.One major difference is in how data is sent and received on a socket.ESOCK provides four different socket types:1.Stream – A stream socket provides a byte-oriented, reliable datachannel.
‘Byte-oriented’ means data can be written or read in arbitrarylengths; ‘reliable’ means that data is guaranteed to arrive in order atthe receiver without duplication or loss, or not to be received at all.Examples: TCP (TCP/IP), RFCOMM (Bluetooth).2.Sequenced packet – A sequential packet socket provides a reliable,packet-based interface. ‘Packet-based’ means data must be writtenin blocks of length no larger than the maximum packet size, and isread as individual packets.
This means that the sender must knowthe maximum size of the outgoing packets and respect this limit. Onthe receive side, each call to Recv() returns the data from a singlepacket, so if the buffer provided is smaller than the size of the packet’sdata the remaining data will be thrown away, and the next read willreturn the next packet’s data. This behavior can be overridden usingthe KSockReadContinuation flag in the Recv() call, in whichOVERVIEW OF ESOCK31case any remaining data will be returned in the next Recv() call.Examples: L2CAP (Bluetooth), Tiny TP (IrDA).3.
Datagram – A datagram socket provides a packet-based interfacethat may be reliable or unreliable, depending on the protocol. In theunreliable case, the sender can usually make no assumption aboutwhether the data arrives at all, out of order or duplicated at thereceiver. The send/receive interface works as for sequential packetsockets. Examples: UDP (TCP/IP), IrMUX (IrDA).4. Raw – A raw socket provides low-level access to the packets beingreceived/transmitted and the ability to freely manipulate these.Types of protocolsCommunications protocols are divided into two families: connectionoriented and connectionless.Connection-oriented protocols (and their associated sockets) requirethat the socket is connected to the peer before data is sent or received,whereas connectionless sockets allow data to be sent without a connection having been established first.Connectionless protocols generally (but not always) provide unreliabledatagram interfaces, as it is difficult to provide reliable data transferwithout a connection, for example to know when to clean up memoryused to store data until it is acknowledged by the receiver.Socket addressesOne of the key classes involved in the use of RSocket is the TSockAddr.This is a standard base class for all socket addresses supported by SymbianOS.
By default it only has one attribute – a port – but each technologycreates its own classes derived from it to add methods for storing theappropriate type of address, e.g., TBTSockAddr, TInquirySockAddr,TInetAddr, TIrdaAddr.The use of this base class is the reason that, providing you to performa lookup using a DNS name and do not try to manipulate the underlyingaddress, use of IPv4 and IPv6 is transparent for all applications – evenapplications written before IPv6 was created!Lifecycle of a socketFigure 3.1 shows the lifecycle of a socket.Opening a socket SocketsRSocket::Open() calls:areopenedusingtheTInt Open(RSocketServ& aServer,TUint addrFamily,TUint sockType,TUint protocol);various32AN INTRODUCTION TO ESOCKTInt Open(RSocketServ& aServer,TUint addrFamily,TUint sockType,TUint protocol, RConnection& aConnection);TInt Open(RSocketServ& aServer,TUint addrFamily,TUint sockType,TUint protocol, RSubConnection& aSubConnection);TInt Open(RSocketServ &aServer,const TDesC& aName);TInt Open(RSocketServ& aServer);As you can see, each of these take a RSocketServ parameter,which must be a connected session to ESOCK.
The first four versionsof Open() associate the socket with a specific protocol and/or connection/subconnection (described below). The protocol can be identifiedeither by the <addrFamily, sockType, protocol> tuple, or by name. Thefifth version allows a blank socket to be created, which is used forincoming connections.To find the correct <addrFamily, sockType, protocol> values, you caneither look in the Symbian OS documentation, or use the protocol enumeration methods of RSocketServ to see what’s available on your device.Table 3.1 shows some of the common values for Symbian OS v9.x.RSocket::Close() can becalled from any state andwill return the socket tothe Closed state,cleaning up anyresources or outstandingrequestsStartClosedOpen(RSocketServ&)Open(RSocketServ&, ...)OpenCancelConnect()(if reconnectable)CancelConnect()non-reconnectableBlankListen()Connect()ConnectingListeningProtocol disconnectsReconnectable socketAccept()Called on listening socket withblank socket as parameterErrorAll operations willreturn errors.Close() is onlyavailableoperationShutdown()Shutting DownConnectedProtocol disconnectsnon-reconnectable socketDisconnectedShutdown(EImmediate)DeadFigure 3.1All operations willreturn errors.Close() is onlyavailableoperation.
Noteno way back toOpen orConnected stateThe lifecycle of a socketAll operations willreturn errors.Close() is onlyavailableoperationOVERVIEW OF ESOCK33Table 3.1 Protocol valuesFamilyProtocolProtocol nameaddrFamilysockTypeProtocolIPv4/6TCPtcpKAfInetKSockStreamKProtocolInetTcpIPv4/6UDPudpKAfInetKSockDatagramKProtocolInetUdpIPv4/6ICMPicmpKAfInetKSockDatagramKProtocolInetIcmpIPv6ICMPicmp6KAfInet6KSockDatagramKProtocolInet6IcmpBluetoothRFCOMMRFCOMMKBTAddrFamilyKSockStreamKRFCOMMBluetoothL2CAPL2CAPKBTAddrFamilyKSockSeqPacketKL2CAPBluetoothAVCTPAVCTPKBTAddrFamilyKSockDatagramKAVCTPBluetoothAVDTPACDTPKBTAddrFamilyKSockDatagramKAVDTPBluetoothLink ManagerBTLinkManagerKBTAddrFamily(Host resolver)KBTLinkManagerIrDATiny TPIrTinyTPKIrdaAddrFamilyKSockSeqPacketKIrTinyTPIrDAIrMUXIrmuxKIrdaAddrFamilyKSockDatagramKIrmuxConnecting a socket As all communication involves at least two parties,there are two directions in which a connection can be made betweenyour program and a peer.
Either the connection is initiated by yourprogram (an ‘active’ connection), or your program waits to receiveconnections from a peer (a ‘passive’ connection). These roles havealso traditionally been called ‘client’ and ‘server’, reflecting the normalpractice of having a client program connecting to a server to request aservice. However, once the connection has been made there may beno difference between the two ends and the link can be used in anyway. For example, in a multiplayer game both ends may be identicalsoftware which sends game data back and forth with no ‘client’ or‘server’ roles.Active connections An active connection to a peer is usually madeusing the RSocket::Connect() call, although this doesn’t have to beused for connectionless sockets:void Connect(TSockAddr& anAddr,TRequestStatus& aStatus);void Connect(TSockAddr& anAddr,const TDesC8& aConnectDataOut,TDes8& aConnectDataIn,TRequestStatus& aStatus);The address of the device to connect to is passed in the TSockAddrparameter.
Since the addressing information needed by each protocol is34AN INTRODUCTION TO ESOCKdifferent, most protocols provide a class derived from TSockAddr thatcontains the specific information needed by that protocol. This can thenbe passed to the RSocket::Connect() call as a TSockAddr. Connect() can be used with both connection-oriented and connectionlessprotocols – with the latter it simply sets the default address for outgoingpackets to be sent to, as there is no connection to initiate.Connect() is an asynchronous call, reflecting the fact that creatinga connection may take a substantial amount of time – potentially severalseconds or more, depending on the technology in use.
Your programshould be prepared to deal with these delays, and the variation betweendifferent bearers.The second version of Connect() allows for additional data to besent/received during the connection. This is only supported by some protocols – you can determine if the protocol you’re using supports this by usingthe RSocket::Info() or RSocketServ::GetProtocolInfo()methods to retrieve details on the protocol. These are returned in aTProtocolDesc structure, of which the iServiceInfo member provides various flags:// iSock is a opened socketTProtocolDesc desc;iSock.Info(desc);if(desc.iServiceInfo & KSIConnectData){// Protocol supports connection data –}else{// it doesn’t}can use Connect() with dataSince connection data is not supported by all protocols, most programsdon’t make use of this facility, because it can be replaced by making aconnection and then sending the data which works for all protocols.
Ingeneral it’s worth avoiding relying on quirks and unique features of aparticular protocol, as in future your program may need to support otherprotocols.The iServiceInfo field in TProtocolDesc has lots of other information on the protocol. The details are shown in Table 3.2.As normal, the returned value in the TRequestStatus indicates ifthe connection was created successfully. If the value is KErrNone, thenthe socket is now connected and can be used for data transfer.