Wiley.Developing.Software.for.Symbian.OS.2nd.Edition.Dec.2007 (779887), страница 64
Текст из файла (страница 64)
An explicit connection neednot even be made since the destination endpoint can be defined,packet by packet, when data is sent (unlike for TCP, where all sockettransfers occur between the endpoints of the established connection).3.Transfer data between client and server.The client can now read and write data to the communication pathusing the socket.4.Close the socket.NETWORK PROGRAMMING USING SOCKETS329When the communication session is completed, the socket is closed.Note that, in the case of a client, the programmer need not explicitlyassign a port number. The client address is automatically assigned arandom port number during the connect phase (for TCP) or send (forUDP).
This automatic assignment works since the specific client portnumber does not really matter; the server simply returns data to thesource port it is communicating with.Server-side code1. Create the server-side socket.2. Bind an endpoint address to the server socket.Unlike in the case of a client, the programmer must make an explicitcall to a bind() function to assign the endpoint address. The socketis assigned to the known port number for the particular service offeredand, of course, the IP address must be one that is assigned to thatmachine.3. Process client connections.For TCP, the server-side socket will get connection requests fromclients. For each client connection request, a new socket handle iscreated to represent that particular client connection.
The originallyopened socket is still maintained though, to continue looking for newclient connections. Usually the server software will create a separatethread for each client connection it receives, and that thread uses thenewly created connection socket handle to communicate with theclient.For UDP, unlike with TCP, there is no automatic connectioncapability for sockets, so UDP server programming is more involved.The server receives all raw UDP packets that clients send to that IPaddress/port.
It is up to the server program to set up data structuresand logic to filter the data and create connections, as well as doinganything else that is required for that service.4. Transfer data with the client.The server transfers data to and from the client via the socket’s sendand receive functions.5. Close the socket.When the connection is complete, the socket is closed.11.2.2BSD C Socket APIBSD Unix defines a set of C socket functions for creating and using sockets.Many operating systems use this API for network communication, and ithas practically become a de facto standard for network programming.330SYMBIAN OS TCP/IP NETWORK PROGRAMMINGBefore looking at the Symbian OS socket API, let’s look at a simpleexample using the BSD C API and then go through some of the functions.
Iwill then refer to this when describing the Symbian OS C++ native socketAPI, which is similar to the BSD API in many ways. I will concentrateon client-side software only, since not many servers are implemented ona smartphone!Note that Symbian OS v9 also supports the BSD C-based socket APIas part of the standard C library provided by the P.I.P.S. libraries.2 Thiscan be convenient for porting network code from other operating systemsto Symbian OS; however, in most cases you’ll want to use the nativeSymbian C++ socket API described in the next section.11.2.3 BSD C API Socket Client ExampleThe following code shows a simple program to fetch a web page usingTCP on a server’s port 80 (web server port) and to print the HTTP data tothe screen.int OutputWebPage( char *servName, char* urlDoc){int sock;struct sockaddr_in server;struct hostent *hp;char buffer[1024];// create socketsock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0){fprintf(stderr,"Error opening stream socket\n");return -1;}// Connect socket using name specified by command lineserver.sin_len = sizeof(server);server.sin_family = AF_INET;hp = gethostbyname(servName);if (hp == 0){fprintf(stderr, "%s: unknown host\n", argv[1]);return(-1);}memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);server.sin_port = hton(80); // set to well-known HTTP server port 80if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0){fprintf(stderr,"Error connecting stream socket");return(-1);}2P.I.P.S.
stands for P.I.P.S. Is POSIX on Symbian OS. The P.I.P.S. libraries provide libc,libdl, libm, and libpthread for Symbian OS v9, replacing the previous partial supportfor standard C on Symbian OS offered by estlib.More information about P.I.P.S. can be found on the Symbian Developer Network wiki(http://developer.symbian.com/wiki/display/oe/P.I.P.S.+Home).NETWORK PROGRAMMING USING SOCKETS331// send a HTTP GET to web serversprintf(buffer, "GET %s\n", urlDoc);nRet = send(sock, buffer, strlen(buffer), 0);if (nRet <= 0){printf(stderr,"Error on send().\n");close(Socket);return -1;}// Receive the file contents and print to stdoutwhile(1){// Wait to receive, nRet = NumberOfBytesReceivednRet = recv(sock, buffer, sizeof(buffer), 0);if (nRet <= 0)break;puts(buffer);}close(sock);return 0;}In this example, the function OutputWebPage() retrieves a webpage from the server specified in the first argument, accessing the sourcewith the specified URL document name (blank just gets the home page).An example invocation is:OutputWebPage(www.yahoo.com," ");which retrieves and prints the HTML source of Yahoo’s home page.Creating the socketFirst, the client socket is created by the line:sock =socket (AF_INET, SOCK_STREAM, 0);This creates a TCP socket to be used in communicating with the webserver.
The function socket() is prototyped as follows:int socket(int domain, int type, int protocol)where domain is AF INET for TCP/IP, type is SOCK STREAM for TCPor SOCK DATAGRAM for UDP, and protocol indicates the specificprotocol for the type. In this case, protocol can be set to zero, sinceTCP and UDP are the only protocols in AF INET for those types.socket() returns an integer handle for the socket, which is used asa reference in subsequent socket function calls.332SYMBIAN OS TCP/IP NETWORK PROGRAMMINGConverting domain names to IP addressesNext, the server name is converted to an IP address as follows:server.sin_len = sizeof(server);server.sin_family = AF_INET;hp = gethostbyname(servName);if (hp == 0){fprintf(stderr, "%s: unknown host\n", argv[1]);return(-1);}memcpy((char *)&server.sin_addr, (char *)hp->h_addr, hp->h_length);server.sin_port = hton(80); // set to well-known HTTP server port 80IP addresses are hard for people to remember, so ASCII names – knownas domain names – are used instead.
It’s much easier to rememberwww.yahoo.com, for example, than it is to remember 216.109.118.77.The BSD function gethostbyname() converts the server name to anIP address using what is known as the Domain Name System (DNS). DNSis a service used in TCP/IP networks, which translates human-readabledomain names to IP addresses. DNS is a complex system due to thebillions of IP addresses in use, which change every day – but fortunatelyas a network programmer, it is easy to use.The port address (server.sin port) is set to 80, which is the portnumber for HTTP web pages.Connecting the socketNow that the software has the IP address and port, it performs a TCPconnection to the server’s HTTP endpoint as follows:if (connect(sock, (struct sockaddr *)&server, sizeof(server)) < 0){fprintf(stderr,"Error connecting stream socket");return (-1);}The function connect() connects a socket whose handle is specified asthe first argument, to a destination endpoint whose address is specifiedin the second argument (with the address structure’s size specified inargument three).
For TCP this consists of a packet exchange between theendpoints to establish a virtual connection.In the case of UDP, this connect() just associates the socket withthe destination address so that the programmer need not supply theNETWORK PROGRAMMING USING SOCKETS333address on each send. In this example, we are establishing a TCPconnection, however.The hardest part about using connect() is setting up the datastructures to specify the endpoint address to connect to. I will not go intothe data structure in detail here, but the form of address setup shown inthe example is fairly typical.Sending dataNext, the HTTP GET request is sent to the server through the connectedsocket as follows:sprintf(buffer, "GET %s\n", urlDoc);nRet = send(socket, buffer, strlen(buffer), 0);send() is used to send a buffer to the remote endpoint through thesocket whose handle is passed as the first argument.
It has the form:int send(int socket, const void *buff, size_t len, int flags);send() returns the number of bytes sent. If it is a negative number, thenan error occurred.For UDP sockets, you can use sendto() for sending UDP packets. Itis the same as send() except you specify the address of the endpoint tosend the data to. It is defined as:int sendto(int s, const void *msg, size_t len, int flags,const struct sockaddr *to, socklen_t tolen);Receiving dataWhen the server gets the HTTP GET request, it will start sending the webpage to the client.