Communication between iOS App local socket

  • 2020-11-25 07:35:38
  • OfStack

Previously, I saw an article that introduced 5 communication modes between App, which include URL Scheme, Keychain, UIPastedboard, UIDocumentInteractionController and using socket for local communication. The first four are useful, and relatively simple, a few lines of code. For the last one, I haven't used 1 before (forgive me for being a white dog), so I tried to write it down today, and I will share it here.

Well, without further ado, let's begin:

First of all, the principle of App is very simple. One App performs bind and listen of TCP on the local port, and another App performs connect on the local port. Thus, a normal TCP connection can be established, and data can be transmitted whatever it wants. Let's start by creating the server:

1. First, create a socket with the socket() function


/*
* socket return 1 a int Value, -1 Failed to create 
*  The first 1 Three parameters indicate the protocol family / The domain   There are usually AF_INET(IPV4) , AF_INET6(IPV6) , AF_LOCAL
*  The first 2 Parameter designation 1 Types of interfaces: SOCK_STREAM,SOCK_DGRAM , SOCK_SEQPACKET Etc. 
*  The first 3 Parameters specify the corresponding transport protocol, such as TCP/UDP , etc. 1 A set to 0 To use the default value 
*/
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1){
close(sock);
NSLog(@"socket error : %d",sock);<br> return;
}


/*
 * socket return 1 a int Value, -1 Failed to create 
 *  The first 1 Three parameters indicate the protocol family / The domain   There are usually AF_INET(IPV4) , AF_INET6(IPV6) , AF_LOCAL
 *  The first 2 Parameter designation 1 Types of interfaces: SOCK_STREAM,SOCK_DGRAM , SOCK_SEQPACKET Etc. 
 *  The first 3 Parameters specify the corresponding transport protocol, such as TCP/UDP , etc. 1 A set to 0 To use the default value 
 */
int sock = socket(AF_INET, SOCK_STREAM, 0);
if(sock == -1){
 close(sock);
 NSLog(@"socket error : %d",sock);<br> return;

}

2. Bind the local address and port number


//  Address structure data, record ip And port number 
struct sockaddr_in sockAddr;
//  Declare the protocol used 
sockAddr.sin_family = AF_INET;
//  Get the native ip And converted into a char The type of 
const char *ip = [[self getIPAddress] cStringUsingEncoding:NSASCIIStringEncoding];
//  will ip Assign a value to the structure, inet_addr() Function is to 1 A dotted 10进制的IP Converted to 1 Long integer type number 
sockAddr.sin_addr.s_addr = inet_addr(ip);
//  Set the port number, htons() Converts an integer variable from host byte order to network byte order 
sockAddr.sin_port = htons(12345);
/*
 * bind Function to associate a socket 1 Number of addresses, return 1 a int Value, -1 For failure 
 *  The first 1 Parameter specifies the socket, which is the preceding socket The function call returns a frontal socket 
 *  The first 2 The specified address 
 *  The first 3 The size of the address data 
 */
int bd = bind(sock,(struct sockaddr *) &sockAddr, sizeof(sockAddr));
if(bd == -1){
 close(sock);
 NSLog(@"bind error : %d",bd);
 return;

}

3. Monitor the binding address


/*
 * listen The function USES the active connection socket interface to become the connected interface, making it possible to accept requests from other processes and return 1 a int Value, -1 For failure 
 *  The first 1 The number of parameters is before socket The socket returned by the function 
 *  The first 2 The number of parameters can be understood as the maximum limit of the connection 
 */
int ls = listen(sock,20);
if(ls == -1){
 close(sock);
 NSLog(@"listen error : %d",ls);
 return;
}

4, the following is the connection waiting for the client, using accept()(accept function will block the thread, during the process of waiting for the connection will be 1 stuck, so it is recommended to put it in the child thread)


// 1. open 1 Child threads 

NSTread *recvThread = [[NSThread alloc] initwithTarget:self selector:@selector(recvData) object: nil];
[recvThread start];

- (void)recvData{
 

// 2. Wait for the client to connect 

//  The statement 1 An address structure used to receive the address returned by the client  
 struct sockaddr_in recvAddr;
//  Address size 
 socklen_t recv_size = sizeof(struct sockaddr_in);
/*
 * accept() The function returns after a successful connection 1 A new socket (self.newSock) For sending and receiving data later and before the client 
 *  The first 1 Is the socket listened to before , It used to be a local variable, but now it needs to be global 

 *  The first 2 A parameter is 1 A result parameter, which is used to receive 1 A return value that specifies the address of the client 
 *  The first 3 So is the number of parameters 1 A result parameter, which is used to receive recvAddr The consignment of a structure, indicating the number of bytes it occupies 
 */
self.newSock = accept(self.sock,(struct sockaddr *) &recvAddr, &recv_size);
// 3. When you come here, you're connected 1 A new client, the following can be sent and received data, mainly used send() and recv() function 
 ssize_t bytesRecv = -1; //  Returns the size of a data byte 
 char recvData[128] = ""; //  Returns the data cache 
//  if 1 The end is disconnected, recv I'll come right back, bytesrecv Is equal to the 0 And then while Cycle will be 1 Direct execution , So this is equal to 0 Is out 
 while(1){
 bytesRecv = recv(self.newSocket,recvData,128,0); // recvData Is the data received 
 if(bytesRecv == 0){
 break; 

 }

 }

}

5. Send data


- (void)sendMessage{ 

 char sendData[32] = "hello client";

 ssize_t size_t = send(self.newSocket, sendData, strlen(sendData), 0);

 

}

The client side is mainly divided into: create a socket, obtain the host address of the server according to ip and port number, and then connect, after the successful connection can send and receive data to the server, let's look at the code below.

1. Use socket function to create socket as shown in Server 1


int sock = socket(AF_INET, SOCK_STREAM,0);

if(sock == -1){

 

 NSLog(@"socket error : %d",sock);

 return;

}

2. Get the address of the host


NSString *host = [self getIPAddress]; //  Access to the machine ip address 
//  Returns the host name and address information corresponding to the given host name hostent Structure pointer 
struct hostent *remoteHostEnt = gethostbyname([host UTF8String]);
if(remoteHostEnt == NULL){
 close(sock);

 NSLog(@" Unable to resolve server hostname ");
 return;
}<br>//  Configure the socket to connect to the host ip Address and port number used for connect() function 
struct in_addr *remoteInAddr = (struct in_addr *)remoteHost->h_addr_list[0];
struct sockaddr_in socktPram;
socketPram.sin_family = AF_INT;
socketPram.sin_addr = *remoteInAddr;

socketPram.sin_port = htons([port intValue]);

3. Use connect() to connect to the host


/*
 * connect Functions are commonly used for client resumes tcp Connect to the host at the specified address, the function returns 1 a int Value, -1 For failure 
 *  The first 1 The parameters for socket Function to create a socket that represents the socket to connect to the specified host 
 *  The first 2 The parameters are sockets sock The host address and port number you want to connect to 
 *  The first 3 Is the host address size 
 */
int con = connect(sock, (struct sockaddr *) &socketPram, sizeof(socketPram));
if(con == -1){
 close(sock);
 NSLog(@" The connection fails ");
 return;

}

NSLog(" The connection is successful "); //  Coming here means connecting successfully; 

4, after the successful connection can send and receive data


- (IBAction)senddata:(id)sender {
 //  To send data 
 char sendData[32] = "hello service";
 ssize_t size_t = send(self.sock, sendData, strlen(sendData), 0);
 NSLog(@"%zd",size_t);
}
 

- (void)recvData{
 //  Take the data and place it in the child thread 
 ssize_t bytesRecv = -1;
 char recvData[32] = "";
 while (1) {
 
  bytesRecv = recv(self.sock, recvData, 32, 0);
  NSLog(@"%zd %s",bytesRecv,recvData);
  if (bytesRecv == 0) {
   break;
  }

 }

}

Ok, use socket to communicate locally between App and App and that's it. The first time To write a blog, 1 is to record my experience, 2 is to share with you 1, there are mistakes in the article hope you can point out. Finally, the address of Demo is attached. For those who are interested in Demo, please check below:


Related articles: