IOS Socket Finishing and Cocoaasyncsocket, Srwebsocket source Parsing (a)

Source: Internet
Author: User
Tags ack connect socket sendmsg install node htons

Write in preparation:

Socket communication in iOS is also very common, I have been learning Telegram this open source project, Telegram is on the basis of the socket to do instant messaging, this is believed to understand this open source project also know that I hope I can slowly understand it's this Mtprotokit open source Protocol, im this piece of things I have written a "IOS Instant Messaging + Imitation Chat framework + source", from the click on the volume of the really this piece of things our demand is still very large, "IOS Instant Messaging + Imitation Chat framework + SOURCE "This article because of their own last year is limited, and now I go to see also will feel a lot of places not satisfactory, the next socket can say this a series of their own ready to seriously write down, can not be anxious, hoping to seriously solid to this series of things summed up, At least make yourself feel summed up a little more comprehensively.

What is a socket?

We start with some of the commonly used protocols to understand the socket, do not want to directly throw the concept of the socket, in the mind there is this problem on the line! Later we will step by step to find the answer! Here are the first two links:

"iOS instant messaging, from getting started to" giving up "?" This article carefully said that the iOS instant messaging this piece of the author's own understanding and summary, can be very good to help us understand the instant communication, just a bit long, it takes a little time to see.

"About iOS sockets are here" This article I also feel very good after the article said that if you can help us understand the instant messaging, then this article will help us digest the socket.

The above two articles I believe will help us will be very big, so is highly recommended! Combined with these two articles, we began to slowly summarize the socket, in the article all the practice demo and the detailed integration process of the demo will be for everyone. After a year, ask yourself how to achieve instant messaging?

(1) Third-party IM services

Third party can do instant communication is in is too many, ring letter, Melt Cloud, NetEase cloud letter and so on .... Talk about my own understanding:

1, their technology is indeed no problem, is OK. If your entire development team technical strength General (the general company's entire team technology in fact, the actual strength of the general, including some of my own company), as well as before your company did not make instant communications and there is a point is to want to crash, then I recommend the use of third-party! This point to say that my own personal experience will be more real, I am the first company, the project has the need for instant communication, we are using the socket to do, and finally did not make a satisfactory instant communication, the loss of the message, link state instability, At the beginning of the time also did not think about the information security these issues, the second home with the first lesson to combine the strength of the whole team, choose to use the ring letter to do, the overall feeling than the first good many, until now contact with the telegram, just feel that the general company is recommended to use a third party, That will at least guarantee that your functionality is no problem.

2, the third party's malpractice, charges! Customization level is not fully in your hands, charge this point, like NetEase these at the beginning of the clear how the price for you to choose, such as the ring letter, will be in a suitable time, when your users accumulate to a certain amount of time to start charging. This cost must be considered at the time of development.

3, there is no way to really improve your understanding of instant messaging and level of improvement.

(2) have the ability to do it yourself

Have the ability to do their own sure is the best, this time you need to be well certified to learn all aspects of instant messaging, this process you will certainly be a great harvest, but the difficulties will certainly have, need to weigh themselves, do, how do we start? Here's a summary of what we should know when we start doing instant messaging ourselves.

Instant Messaging DIY--Choose

At this point you need to choose the transport protocol we use: TCP or UDP

Of course, before you choose, you must know what TCP is? What is UDP? (Here is a digression, in the beginning of contact with iOS, often see some people spit groove, I do iOS, interview often encountered someone asked what is TCP what is UDP, I need to understand these why? Is it useful? Is it necessary? I do not know how you can work a few years after working, you will feel that then you are very sentimental? These need to grasp the necessity I do not mention, I also believe that this article friends will not have this idea!)

This choice question, I gave to an instant communication network on the better Article conclusion: Article link "mobile im/push System Protocol selection: UDP or TCP?" "Hope that the friends need to take a serious look." Here is the final conclusion of the article:

Take a look at the article, Transfer Protocol I'm sure you can make the right choice, then you'll have to consider which of the chat protocols, so the theme of this piece is--choose

Chat protocols are summarized here to compare the pros and cons of some of them:

The above summary helps us to differentiate between these protocols, and it is clear that we are doing instant messaging ourselves. The best choice or use socket to achieve, the following summarizes some of their own learning after the socket understanding, if there is something wrong, we can point out.

Socket understanding

Socket (Chinese name: socket) is the cornerstone of communication, is to support the TCP/IP protocol network communication Basic operating unit, socket itself is not a protocol, socket is the essence of Programming Interface (API), is the encapsulation of TCP/IP. Through the socket, we can better use the TCP/IP protocol, rather than only through the socket we can use the TCP/IP protocol. Without the socket, we have to face the TCP/IP protocol of the Transport layer, the workload will be greater, the difficulty will be greater!

Establishing a socket connection requires at least a pair of sockets, one of which runs on the client, called Clientsocket, and the other running on the server side called ServerSocket.

Here is Baidu's search for a socket using the TCP protocol to establish a connection flowchart:

In fact, this entire step includes its connection, the client sends the message and reads the message, the server receives the message and sends the message to the client and to the last disconnected request, and so on, we first look at the entire connection process, It has been summed up by some of the following steps: (the previous initialization process does not mention, this own attention on the line)

1, Server monitoring: Server-side sockets do not locate the specific client socket, but in the state of waiting for the connection (that is, the above blocking until the client connection), real-time monitoring network status, waiting for the client connection request.

2, client request: The client initializes the socket to make a connection request, the target to connect is the server-side socket. To do this, the client's socket must first describe the socket of the server it is connecting to, indicate the address and port number of the server-side socket, and then make a connection request to the server-side socket. (This process can be deepened in understanding this step when you initialize the socket in your client connection)

3, Connection confirmation: When the server socket is heard or received the client socket connection request, in response to the client socket request, set up a new thread, the server-side socket description to the client, once the client confirmed the description, the two sides formally establish a connection. While the server-side socket continues to be in the listening state, it continues to receive connection requests from other client sockets.

Through the process above, your socket is connected to the server socket!

Add: We can use the (Transport Layer) TCP/IP protocol when transmitting data, but then, if there is no application layer, the data content cannot be recognized, if you want to make the transferred data meaningful, you must use to the Application layer protocol, the application layer protocol has many, For example, we often say that HTTP (HTTP is the application layer of the Protocol, it is actually built on the TCP protocol). The web uses the HTTP protocol as an application-layer protocol to encapsulate HTTP text information and then send it to the network using TCP/IP as the Transport layer protocol.

Between HTTP and socket, this example of Baidu is also used by a lot of blogs: http is a sedan that provides a specific form of encapsulating or displaying data; the socket is the engine that provides the ability to communicate on the network.

Above these you have to understand the tcp,udp above, the network level of these things, understand this socket will be much easier! Therefore, it is recommended to understand tcp,udp these protocols, like the TCP connection when the three-time handshake, the time of disconnection four waves. The difference between it and UDP, as well as the characteristics of the HTTP these are good to understand, these I have not summed up before, and so finish to summarize some of these network levels and these protocols.

The above said the connection of the socket, then we will understand again and it is always together with a few problems: heartbeat mechanism pingpong mechanism disconnection reconnection

One: Heartbeat mechanism

Heartbeat generally refers to a certain end (most of the time the client) sends a custom instruction to the server at regular intervals to determine if the two sides are alive, as it is sent at a certain interval, similar to the heartbeat, so everyone calls it a heartbeat mechanism. About the heartbeat after we introduced here in the back of the demo I will give you the source, concrete can be combined with the source code to see.

Socket selection TCP Transport protocol established a connection, this TCP protocol has a KeepAlive mechanism, the following article is also very clear why can not use the TCP protocol KeepAlive mechanism to do heartbeat reasons, the conclusion is: TCP KeepAlive is used to detect the dead and alive of the connection, not to detect if the connection is available! And our heartbeat is to detect the connection between the dead and alive at the same time to detect whether the connection is available!

Besides, you keep a long connection with your heartbeat, how do you design your heartbeat plan? At the bottom of the reference article, there are two views, first look at the diagram:

Reference article why does TCP-based mobile im still need a heartbeat keepalive? 》

Summarize the above two ways to reduce the timing of your heartbeat:

1, consider the timing of the time interval problem, this problem in fact sometimes in the interview will also be asked, how to determine the heartbeat time interval or reduce heartbeat, etc., the first one is in the timing of the time interval to consider. This specific time setting how much, we will say carefully below.

2, from the end of the message to start the cycle time rather than the design of a fixed interval, this my own understanding, received the message when you do the mark time, if in a certain time and the message received, do not heartbeat, if in a certain time did not receive the message on the heartbeat. Of course you receive the message in your time, this timing must also be refreshed, this involves specific practical details.

The service side and we said above the same reason!

Derivative question: How do you set this time interval? One of the recommended articles at the beginning of our article is a more detailed explanation of the problem:

The specific reason for this--NAT timeout, you have to be interested can click to go to Baidu specific understanding of what is a NAT timeout, here we do not occupy space to write this, suggest or in our most recommended article to understand this NAT timeout, Let's talk about our results: While domestic carriers typically have a NAT timeout of 5 minutes, our heartbeat is usually set at a time interval of 3-5 minutes.

Two: Pingpong mechanism

This is to appear in the heartbeat interval we set up a connection problem, as the reference to the article that we are in the subway elevator in these places, then what is it specifically?

When the server sends out a Ping client that does not return a response within the agreed time, the client is considered to be ack out of line, and we Server are actively disconnecting and Scoket APNS sending the message in a push-to-send manner.

Also when the client goes to send a message, because we are slow to receive the server Response ACK packet, it indicates that the client or the server is no longer on the line, we will also show that the message sent failed, and disconnected ScoketConnection. Talk about their understanding: This mechanism is to prevent the appearance of the connection is not a problem, but in fact, the issue of the message, you send you a message through the server, OK Server will give you the corresponding response, if not receive the response, you handle the failure, disconnect the socket, here is a simple understanding: three: Disconnecting a heavy connection

Our own initiative to disconnect the Scoket connection (log out, the app exits to the background, etc.) is not required to reconnect. The other connection disconnects, we all need to make a wire break reconnection, the general solution is to try to reconnect a few times, if you still cannot reconnect successfully, then no longer reconnect. This simple to understand, know on the line.

The above-mentioned theory of the socket, we have almost said, the following is the focus of the code through the digest of the above-mentioned theoretical knowledge.

Look at the main ways of sockets

Next take a look at the socket in the iOS source code inside there are some things, you can first look at, create a file, import #import <sys/socket.h> can go inside the socket to see what is inside. It is mainly the following set of interfaces, gives us its method, we have a careful analysis of it below:

In the whole process we said earlier, we summarize the entire process by which a client sends a message using a socket:

1. Initialize socket using int socket (int, int, int)

2. How to connect socket using int connect (int, const struct SOCKADDR *, socklen_t)

3, send, receive data using method ssize_t Send (int, const void *, size_t, int)/ssize_t recv (int, void *, size_t, int)

ssize_t sendto (int, const void *, size_t,int, const struct SOCKADDR *, socklen_t) and

ssize_t recvfrom (int, void *, size_t, int, struct sockaddr * __restrict, socklen_t * __restrict)

There is a difference between the above method of sending, and in the comments below we add a description.

4. How to close the socket use Close () This method in the back I said, in the socket source code is not see this method.

Here are some comments on the methods of some of the socket methods:

/* In order to ensure that the order of reading and the order of the source code, convenient for everyone to view, do not adjust the method sequence, such as the initialization of the method location is not adjusted. The explanation is also the main, not all explained __begin_decls This method is used in the server, to accept the client request, and say that the client's network address is saved in the SOCKADDR type pointer __restrict, the following __ Restrict is the length of the address intaccept (int, struct sockaddr * __restrict, socklen_t * __restrict) __darwin_alias_c (accept); Binds the socket to the specified host address and port number, and the binding returns 0 successfully. Failed to return 1, this method you can see in the Cocoaasyncsocket source code intbind (int, const struct SOCKADDR *, socklen_t) _ _darwin_alias (BIND); Client socket connection method, successfully returned 0, failed to return 1, the first parameter is you initialize a socket to get to the file descriptor, initialize the socket returned by the file descriptor is the int type, this you can see below. The second parameter is a pointer to the SOCKADDR structure to connect to the socket, and the third parameter represents the byte length of the sockaddr struct reference: https://baike.baidu.com/item/connect%28%29/ 10081861?fr=aladdinintconnect (int, const struct SOCKADDR *, socklen_t) __darwin_alias_c (connect); Get the address reference for the socket: https://baike.baidu.com/item/getpeername%28%29intgetpeername (int, struct sockaddr * __restrict, socklen_t * __restrict) __darwin_alias (getpeername); Get the name of the socket reference: https://baike.baidu.com/item/getsockname%28%29intgetsockname (int, struct sockaddr * __restrict, socklen_t * __restrict) __darwin_aLIAS (getsockname); https://baike.baidu.com/item/getsockopt%28%29intgetsockopt (int, int, int, void * __restrict, socklen_t * __restrict); For the server listener client, pass the two parameters one is to initialize the socket to obtain the file descriptor, the second is to wait for the maximum length of the connection queue if no error occurs, listen () returns 0. Otherwise, the return-1 method with parameters such as int listen (int sockfd, int backlog), this method is also used in Cocoaasyncsocket source code to judge reference: https://baike.baidu.com/item/ Listen%28%29intlisten (int, int) __darwin_alias (listen); Receive Message method, detail https://baike.baidu.com/item/recv%28%29ssize_trecv (int, void *, size_t, int) __darwin_alias_c (recv); Reading data from a UDP socket ssize_trecvfrom (int, void *, size_t, int, struct sockaddr * __restrict,socklen_t * __restrict) __darwin_al Ias_c (recvfrom); ssize_trecvmsg (int, struct MSGHDR *, int) __darwin_alias_c (recvmsg); Send Message Method reference: https://baike.baidu.com/item/send%28%29#3ssize_tsend (int, const void *, size_t, int) __darwin_alias_c (send) ; Send,sendto and sendmsg system calls are used to send messages to another socket. The Send function can be used when the socket is in a connected state. SendTo and sendmsg can use SSIZE_TSENDMSG (int, const struct MSGHDR *, int) __darwin_alias_c (sendmsg) at any time; SendTo () is suitable for sending non-established connectedReceived UDP packet ssize_tsendto (int, const void *, size_t,int, const struct sockaddr *, socklen_t) __darwin_alias_c (sendto); intsetsockopt (int, int, int, const void *, socklen_t); Shutdown () refers to the prohibition of data receiving and sending on a socket. Intshutdown (int, int);  Intsockatmark (int) __osx_available_starting (__mac_10_5, __iphone_2_0);  The key is to understand the socket initialization, the complete parameter method is this: int socket (int domain, int type, int protocol) domain parameter indicates what type of address to use for example: Pf_inet, Af_inet: Ipv4 network protocol PF_INET6, Af_inet6:ipv6 network protocol The role of the type parameter is to set the protocol type of the communication sock_stream: Provides a stable connection-oriented data transfer, that is, the TCP protocol. OOB: You must use Connect () to establish the connection state before all data is transferred. SOCK_DGRAM: Use a non-contiguous, unreliable packet connection. Sock_seqpacket: Provides continuous and reliable packet connections. Sock_raw: Provides access to the original network protocol. SOCK_RDM: provides reliable packet connectivity. Sock_packet: Communicates directly with the network driver. The parameter protocol is used to specify the transport protocol number used by the socket. This parameter is usually not set specifically, and is typically set to 0.  Reference: Https://baike.baidu.com/item/socket%28%29 above interpretation if combined with Cocoaasyncsocket source to understand, will understand more thoroughly intsocket (int, int, int); Intsocketpair (int, int, int, int *) __darwin_alias (Socketpair), #if!defined (_posix_c_source) intsendfile (int, int, off_ T, off_t *, strUCT SF_HDTR *, int); #endif!_posix_c_source #if!defined (_posix_c_source) | | Defined (_darwin_c_source) void pfctlinput (int, struct sockaddr *); int connectx (int, const sa_endpoints_t *, Sae_associd _t, unsigned int, const struct IOVEC *, unsigned int, size_t *, sae_connid_t *); int disconnectx (int, sae_a ssocid_t, sae_connid_t); #endif (!_posix_c_source | | _darwin_c_source) __end_decls*/

Native socket message sent to receive demo

Here there is no more animated GIF format, afraid that the message sent to receive the map is too big! Or give it, you can see here connected connection success, you can also see the message received data, the last time you disconnect the server close I do not: this demo because of the small comparison, I put the main code out, Demo source will be in this series of articles and the following demo together:

This is the socketmanager of this singleton class. m source, above all have comments, of course, you urgently need source code. Can add me qq to find me, I send you! After this demo, upload!

#import "SocketManager.h" #import <sys/socket.h> #import <sys/types.h> #import <netinet/in.h>#      Import <arpa/inet.h> @interface Socketmanager () @property (nonatomic,assign) int clientscoket; Socket@property (nonatomic,assign) int connetsocketresult;//socket connection result @end@implementation socketmanager/** Note: Inside  Some specific ways to create a socket you don't understand that you can temporarily put down a specific comment on the source of the Cocoaasyncsocket to understand */+ (instancetype) shareinstance{static    Socketmanager * manager = nil;    Static dispatch_once_t Oncetoken;        Dispatch_once (&oncetoken, ^{manager = [[Socketmanager alloc]init]; Manager.connetsocketresult =-1;        Initialize the connection state is a disconnected state//When creating a singleton, initialize the socket and open a new thread to receive the message [manager Initsocket];    [Manager Receivemessagethread];    }); Return manager;}    -(void) initsocket{//Before each connection, first determine whether the connection status 0 in the connection state, the direct return if (_connetsocketresult = = 0) {return;       } _clientscoket = Creatsocket (); Create client Socket const char * server_ip= "127.0.0.1";            Server IP Short server_port = 6969;                Server port//equals 0 indicates successful connection, 1 connection failure if (Connectiontoserver (_clientscoket,server_ip, server_port) = = 0) {        _connetsocketresult = 0;        printf ("Connect to Server success\n");    return;        }else{_connetsocketresult =-1;    printf ("Connect to Server error\n");    }}/** Create socket @return return socket */static int creatsocket () {int clinetsocket = 0;    Note:socket is essentially int type clinetsocket = socket (af_inet, sock_stream, 0); Return the created socket return clinetsocket;} /** Connect socket @param client_socket socket @param server_ip server IP @param port @return Return to successful connection, return 0 connection succeeded, 1 even Connection failed */static int connectiontoserver (int client_socket,const char * server_ip,unsigned short port) {//Generate a sockaddr_in type knot    Structure struct sockaddr_in saddr={0};        Saddr.sin_len=sizeof (SADDR);        Setting the IPV4, this distinction can be seen in the previous interpretation of the socket method of writing the comment saddr.sin_family=af_inet; Inet_aton is an improved way to put aThe string IP address is converted to a 32-bit network sequence IP address//If the function succeeds, the return value of the function is nonzero, and zero is returned if the input address is incorrect.        Inet_aton (server_ip, &saddr.sin_addr);        Htons is to convert integer variables from host byte order to network byte order, assigning port number saddr.sin_port=htons (port);    Prevents the sending of so_nosigpipe signals causing crashes int nosigpipe = 1;        SetSockOpt (Client_socket, Sol_socket, So_nosigpipe, &nosigpipe, sizeof (nosigpipe));    Use the Scoket and server address to initiate the connection.    The client sends a connection request to the server for a specific network address, the connection returns 0 successfully, and the failure returns-1.    Note: This interface call blocks the current thread until the server returns.    int connectresult = connect (client_socket, (struct sockaddr *) &saddr, sizeof (SADDR)); return connectresult;} Open a thread to receive messages-(void) receivemessagethread{nsthread *thread = [[Nsthread alloc]initwithtarget:self selector: @selector (    recieveaction) Object:nil]; [Thread start];} /** Connect socket */-(void) connectsocket{[self initsocket];} /** disconnecting the socket Connection */-(void) disconnectsocket{close (self.clientscoket);}    /** sends a message @param msg message content */-(void) sendmsg: (NSString *) msg{const char * send_message = [msg utf8string]; Send (self.clientscoket,send_message,stRlen (send_message) +1,0);}        /** dead Loop, see if there is a message sent over */-(void) recieveaction{while (1) {char recv_message[1024] = {0};        Recv (Self.clientscoket, Recv_message, sizeof (Recv_message), 0);    printf ("%s\n", recv_message); }} @end

This is the service-side code, first give the code out, below I will be careful to tell you how you run this up!

var net = require (' net ');  var HOST = ' 127.0.0.1 ';  var PORT = 6969;  Create a TCP server instance, call the Listen function to start listening  on the specified port//incoming net.createserver () callback function will act as the "Connection" event handler  //In each "connection" event, the callback function receives a socket object that is unique to the  net.createserver (function (sock) {      ///We get a connection-the connection automatically associates a socket object      Console.log (' CONNECTED: ' +          sock.remoteaddress + ': ' + sock.remoteport);          Sock.write (' Server issued: Connection successful ');      Add a "Data" event handler for this socket instance      sock.on (' Data ', function (data) {          console.log (' data ' + sock.remoteaddress + ') : ' + data ');          Postback the data, the client will receive data from the server          sock.write (' you said "' + Data + '");      });      Add a "Close" event handler for this socket instance      sock.on (' Close ', function (data) {          console.log (' CLOSED: ' +          Sock.remoteaddress + "+ Sock.remoteport);})  . Listen (PORT, HOST);  Console.log (' Server listening on ' + HOST + ': ' + PORT ');

Tell me how the server code works.

Why to say this, because not every iOS development will understand those JS, the above service-side code is I recommend the first article, I wrote this to try, this run up recommended to everyone is this Sublime Text2 this software, this Sublime Text3 is already out, but you can download to the Mac version above can only be sublime Text2, so you can first Baidu to download this thing!

Next, you need to install it node. js, download and install node. js, after you download the installation, you need to add the JS-enabled build system to Sublime Text2, select this New build system ..., add the following code:

{"cmd": ["Node", "$file"], "selector": "Source.js"}

Note: If your node is a step-by-step direct installation, node in the above code will become the absolute path of the node you installed, how to find the absolute path of node??

Simple: Open your terminal which node to get it done!!

End

This blog writing is also spent a long time, due to the length of the problem, can not write a down, and then write it is really too long, after the heartbeat, re-connect and so on the next article summarizes, in the next article intends to combine cocosasnysocket this three-party summary socket remaining problems, and finally , or to the Telegram group to play an advertisement, there are looking at this open source project friends can add the following groups, learn together! Length inevitably may have problems, to have any summary of the bad or problematic places, add me QQ or the following message exchange!

Group number can be pasted directly here: 485718322

IOS Socket Finishing and Cocoaasyncsocket, Srwebsocket source Parsing (a)

Related Article

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.