iOS socket programming

Source: Internet
Author: User
Tags get ip

One, iOS network programming hierarchy Model

in the previous article, "Simple Cocoa Bonjour Network Programming" I introduced how to do Bonjour programming in the Mac system, in that article also introduced in the COCOA network programming hierarchy is divided into three layers, although the demo is a MAC system example, The same is true for iOS systems. The iOS network programming hierarchy is also divided into three tiers:

    • Cocoa Layer: Nsurl,bonjour,game kit,webkit
    • Core Foundation layer: C-based Cfnetwork and Cfnetservices
    • OS layer: BSD socket based on C

The cocoa layer is the topmost objective-c-based API, such as URL access, Nsstream,bonjour,gamekit, etc., which is commonly used in most cases. The COCOA layer is implemented based on the Core Foundation.

Core Foundation layer: Because the direct use of the socket requires more programming work, Apple's socket on the OS layer is simply encapsulated to simplify programming tasks. This layer provides cfnetwork and cfnetservices, where Cfnetwork is also based on Cfstream and Cfsocket.

OS layer: The lowest-level BSD socket provides maximum control over network programming, but it also has the most programming effort. Therefore, Apple recommends that we use the Core Foundation and the API of the above layer to program.

This article will show you how to program with the most basic socket in IOS, which is not very different from socket programming using C + + in the window System.

This article source: Https://github.com/kesalin/iOSSnippet/tree/master/KSNetworkDemo

The results are as follows:

Second, BSD socket API Introduction

The BSD socket API and the Winsock API interface are roughly the same, and the more commonly used APIs are listed below:

API interface Explain
  int  socket  (int addressfamily, int type, 
int protocol)

int Close (int socketfiledescriptor)

Socket   Create and initialize Socket, which returns the file descriptor of the socket, if the descriptor is-1, the creation failed.

close   close socket. The

is typically a parameter addressfamily IPv4 (af_inet) or IPV6 (AF_INET6). Type represents the types of sockets, usually stream stream (SOCK_STREAM) or data message datagram (SOCK_DGRAM). The protocol parameter is typically set to 0 so that the system automatically chooses our appropriate protocol, which is the TCP Protocol (IPPROTO_TCP) for the stream socket, and the UDP Protocol (IPPROTO_UDP) for datagram.

Bind (int socketfiledescriptor,
Sockaddr *addresstobind,
int addressstructlength)

Binds the socket to a specific host address and port number, the successful binding returns 0, and the failure returns-1.

After successful binding, depending on the protocol (TCP/UDP), we can perform different operations on the socket:
UDP: Since UDP is not connected, the UDP socket can be used to transmit data after binding.
TCP: While TCP is required to establish an end-to-end connection, in order to establish a TCP connection the server must call listen (int socketfiledescriptor, int backlogsize) to set the server's buffer queue to receive client connection requests. Backlogsize represents the size of the client connection request buffer queue. When the listen setting is called, the server waits for a client request and then invokes the following accept to accept the client's connection request.

Accept (int socketfiledescriptor,sockaddr *clientaddress, intclientaddressstructlength)

Accepts the client connection request and saves the client's network address information to clientaddress.

When a client connection request is accepted by the server, the link between the client and the server is established and the two can communicate.

Connect (int socketfiledescriptor,sockaddr *serveraddress, intserveraddresslength)

The client sends a connection request to the server for a specific network address, the connection returns 0 successfully, and the failure returns-1.

When the server is established, the client initiates a connection request to the server by invoking the interface. For UDP, the interface is optional, and if the interface is called, the default network address for that UDP socket is set. For TCP sockets This is where the legendary three-time handshake establishes the connection.

Note: This interface call blocks the current thread until the server returns.

gethostbyname (Char *hostname)
Use DNS to find the IP address that corresponds to a specific host name. Returns NULL if the corresponding IP address is not found.
Send (int socketfiledescriptor, char*buffer, int bufferlength, int flags)

Sends the data through the socket, sends the successful return the number of bytes sent successfully, otherwise returns-1.

Once the connection is established, the data can be sent or received via the Send/receive interface. Note A UDP socket that calls connect to set the default network address can also call the interface to receive data.

Receive (int socketfiledescriptor, char*buffer, int bufferlength, int flags)

Reads the data from the socket, the read successfully returns the number of bytes successfully read, otherwise returns-1.

Once the connection is established, the data can be sent or received via the Send/receive interface. Note A UDP socket that calls connect to set the default network address can also call this interface to send data.

SendTo (int socketfiledescriptor,char *buffer, int bufferlength, intflags, sockaddr *destinationaddress, Intdestinationaddresslength)

Send data to a specific network address via a UDP socket, sending a successful return of the number of bytes successfully sent, otherwise return-1.

Because UDP can send data to multiple network addresses, you can specify a specific network address to send data to.

Recvfrom (int socketfiledescriptor,char *buffer, int bufferlength, intflags, sockaddr *fromaddress, Int*fromaddresslength)

Reads the data from the UDP socket and saves the sender's network address information, the read successfully returns the number of bytes successfully read, otherwise returns-1.

Because UDP can receive data from multiple network addresses, additional parameters need to be provided to hold the sender identity of the data.


Third, server workflow

With the above socket API explained, the following summarizes the server workflow.

    1. The server calls the socket (...) to create the socket;
    2. The server calls listen (...) to set the buffer;
    3. Server via Accept (...) Accept client requests to establish a connection;
    4. After the server has established a connection with the client, it can pass the Send (...) /receive (...) Sending or receiving data from the client;
    5. The server calls close to close the socket;

Since iOS devices are typically client-side, there is no code in this article to demonstrate how to set up an IOS server, but you can refer to the previous article: "Bonjour network programming in cocoa" to see how to build a desktop server under a MAC system.

Four, client workflow

Because the IOS device is typically a client, the following shows how to write client code. Let's summarize the client workflow.

    1. The client calls the socket (...) to create the socket;
    2. The client calls connect (...) to initiate a connection request to the server to establish the connection;
    3. After the client has established a connection to the server, it can pass the Send (...) /receive (...) Sending or receiving data from the client;
    4. The client calls close to close the socket;
Five, client code example

The following code implements the workflow for the above client:

- (void) Loaddatafromserverwithurl: (Nsurl *) url{NSString* Host =[URL host]; NSNumber* Port =[url port]; //Create Socket//    intSocketfiledescriptor =Socket(Af_inet, Sock_stream,0); if(-1==socketfiledescriptor) {NSLog (@"Failed to create socket."); return; }        //Get IP address from host//    structHostent * Remotehostent = gethostbyname([host utf8string]); if(NULL = =remotehostent)                {Close (socketfiledescriptor); [Self networkfailedwitherrormessage:@"Unable to resolve the hostname of the warehouse server."]; return; }        structIN_ADDR * remoteinaddr = (structIN_ADDR *) remotehostent->h_addr_list[0]; //Set the socket parameters//    structsockaddr_in socketparameters; Socketparameters.sin_family=af_inet; Socketparameters.sin_addr= *remoteinaddr; Socketparameters.sin_port=htons ([Port Intvalue]); //Connect the socket//    intRET =Connect(Socketfiledescriptor, (structSOCKADDR *) &socketparameters,sizeof(socketparameters)); if(-1==ret)                {Close (socketfiledescriptor); NSString* ErrorInfo = [NSString stringWithFormat:@">> Failed to connect to%@:%@", host, Port];        [Self networkfailedwitherrormessage:errorinfo]; return; } NSLog (@">> successfully connected to%@:%@", host, Port); Nsmutabledata* data =[[Nsmutabledata alloc] init]; BOOL Waitingfordata=YES; //continually receive data until we reach the end of the data//    intMaxCount =5;//just for test.    inti =0;  while(Waitingfordata && i <MaxCount) {        Const Char* buffer[1024x768]; intLength =sizeof(buffer); //Read A buffer ' s amount of data from the socket; the number of bytes Read is returned//        intresult =recv(Socketfiledescriptor, &buffer, length,0); if(Result >0) {[Data appendbytes:buffer length:result]; }        Else {            //if we didn ' t get any data, stop the receive loop//Waitingfordata =NO; }                ++i; }        //Close the socket// Close(socketfiledescriptor); [Self networksucceedwithdata:data];}

As I said earlier, interfaces such as Connect/recv/send are blocked, so we need to put these operations in a non-UI thread. As shown below:

    Nsthread * Backgroundthread = [[Nsthread alloc] initwithtarget:self                                                          selector: @selector ( Loaddatafromserverwithurl:)                                                            object: url];    [Backgroundthread start];

Again, we need to update the UI in order to get the data or the network exception that caused the task to fail, and that's going to go back to the UI thread to do the same thing. As shown below:

- (void) Networkfailedwitherrormessage: (NSString *) message{//Update UI//[[Nsoperationqueue Mainqueue] addoperationwithblock:^{NSLog (@"%@", message); Self.receiveTextView.text=message; Self.connectButton.enabled=YES;    [Self.networkactivityview stopanimating]; }];}- (void) Networksucceedwithdata: (NSData *) data{//Update UI//[[Nsoperationqueue Mainqueue] addoperationwithblock:^{nsstring* Resultsstring =[[NSString alloc] Initwithdata:data encoding:nsutf8stringencoding]; NSLog (@">> Received string: '%@ '", resultsstring); Self.receiveTextView.text=resultsstring; Self.connectButton.enabled=YES;    [Self.networkactivityview stopanimating]; }];}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.