English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
之前看到一篇文章介绍到App之间的五种通信方式,它分别有URL Scheme,Keychain,UIPastedboard,UIDocumentInteractionController以及利用socket进行本地通信。前面4种都有用到过,也相对比较简单,几行代码的事。对于最后一种之前一直没用到过(原谅我还是个小白),所以今天试着写了下,这儿记录在这里和大家分享。
好了,废话不多说,开始:
首先,说下它的原理,其实很简单,一个App在本地的端口进行TCP的bind和listen,另外一个App在本地同一个端口进行connect,这样就建立了一个正常的TCP连接,可以想传什么数据就传什么数据。下面开始先创建服务端:
1zunächst wird mit der socket() Funktion ein Socket erstellt
/* * socket gibt einen int-Wert zurück,-1wenn der Erstellung fehlgeschlagen ist * der erste Parameter gibt die Protokollfamilie an/domäne, normalerweise AF_INET(IPV4)、AF_INET6)、AF_INET6)、AF_LOCAL * der zweite Parameter spezifiziert einen Socket-Typ: SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET usw. * der dritte Parameter spezifiziert das entsprechende Übertragungsprotokoll, wie TCP/UDP usw., wird in der Regel 0 eingestellt, um diesen Standardwert zu verwenden */ int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock == -1{ close(sock); NSLog(@"socket error : %d",sock);<br> return; }
2,bind die Adresse und Portnummer des eigenen Computers
// Adresse Struktur Daten, IP und Portnummer zu speichern struct sockaddr_in sockAddr; // Protokoll erklären sockAddr.sin_family = AF_INET; // IP des eigenen Computers erhalten und in ein char-Typ umwandeln const char *ip = [[self getIPAddress] cStringUsingEncoding:NSASCIIStringEncoding]; // IP an die Struktur zuweisen, inet_addr() ist eine Funktion, die eine dezimale Punktdaten-IP in einen Long-Integer umwandelt sockAddr.sin_addr.s_addr = inet_addr(ip); // Portnummer setzen, htons() wandelt einen int-Wert von der Host-Byte-Reihenfolge in die Netzwerk-Byte-Reihenfolge um sockAddr.sin_port = htons(12345; /* * Die bind-Funktion wird verwendet, um den Socket mit einer Adresse zu verknüpfen und gibt einen int-Wert zurück,-1bedeutet Fehler * der erste Parameter spezifiziert den Socket, der durch den vorangegangenen socket-Aufruf zurückgegeben wurde * der zweite Parameter ist die angegebene Adresse * der dritte Parameter ist die Größe der Adressdaten */ int bd = bind(sock,(struct sockaddr *) &sockAddr, sizeof(sockAddr)); if(bd == -1{ close(sock); NSLog(@"bind error : %d",bd); return; }
3,Adresse, die angehört wird
/* * Die listen-Funktion verwandelt den aktiven Socket-Interface in ein verbindbares Interface, sodass Anfragen anderer Prozesse akzeptiert werden können, und gibt einen int-Wert zurück,-1bedeutet Fehler * der erste Parameter ist der Socket, der durch die vorherige socket-Funktion zurückgegeben wurde * der zweite Parameter kann als die maximale Verbindungslimitation verstanden werden */ int ls = listen(sock,20); if(ls == -1{ close(sock); NSLog(@"listen error : %d",ls); return; }
4,下面就是等待客户端的连接,使用accept()(由于accept函数会阻塞线程,在等待连接的过程中会一直卡着,所以建议将其放在子线程里面)
// 1,开启一个子线程 NSTread *recvThread = [[NSThread alloc] initwithTarget:self selector:@selector(recvData) object: nil]; [recvThread start]; - (void)recvData{ // 2,等待客户端连接 // 声明一个地址结构体,用于后面接收客户端返回的地址 struct sockaddr_in recvAddr; // 地址大小 socklen_t recv_size = sizeof(struct sockaddr_in); /* * accept()函数在连接成功后会返回一个新的套接字(self.newSock),用于之后和这个客户端之前收发数据 * 第一个参数为之前监听的套接字,之前是局部变量,现在需要改为全局的 * 第二个参数是一个结果参数,它用来接收一个返回值,这个返回值指定客户端的地址 * 第三个参数也是一个结果参数,它用来接收recvAddr结构体的代销,指明其所占的字节数 */ self.newSock = accept(self.sock,(struct sockaddr *) &recvAddr, &recv_size); // 3,来到这里就代表已经连接到一个新的客户端,下面就可以进行收发数据了,主要用到了send()和recv()函数 ssize_t bytesRecv = -1; // 返回数据字节大小 char recvData[128] = ""; // 返回数据缓存区 // 如果一端断开连接,recv就会马上返回,bytesrecv等于0,然后while循环就会一直执行,所以判断等于0是跳出去 while(1{ bytesRecv = recv(self.newSocket,recvData,128,0); // recvData为收到的数据 if(bytesRecv == 0){ break; } } }
5,发送数据
- (void)sendMessage{ char sendData[32] = "hello client"; ssize_t size_t = send(self.newSocket, sendData, strlen(sendData), 0); }
Bei dem Client hängt hauptsächlich von: Erstellen Sie Sockets, erhalten Sie die Host-Adresse des Servers basierend auf der IP-Adresse und dem Port, verbinden Sie sich dann, nach dem erfolgreichen Verbindungsaufbau können Sie Daten mit dem Server senden und empfangen, sehen wir uns den Code an.
1Verwenden Sie wie der Server die Funktion socket() zum Erstellen von Sockets
int sock = socket(AF_INET, SOCK_STREAM,0); if(sock == -1{ NSLog(@"Socket-Fehler: %d",sock); return; }
2,erhalten Sie die Adresse des Hosts
NSString *host = [self getIPAddress]; // Erhalten Sie die IP-Adresse des lokalen Computers // Gibt einen Zeiger auf eine hostent-Struktur zurück, die die Hostnamen und Adressinformationen für den gegebenen Hostnamen enthält struct hostent *remoteHostEnt = gethostbyname([host UTF8String]); if(remoteHostEnt == NULL){ close(sock); NSLog(@"Der Hostnamen des Servers kann nicht aufgelöst werden"); return; }// Konfiguration der IP-Adresse und Portnummer des Hosts, den der Socket verbinden soll, für die Funktion connect() 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]);
3Verbindung zum Host über die Funktion connect() herstellen
/* * Die connect-Funktion wird normalerweise für die Erstellung von TCP-Verbindungen durch den Client verwendet, um eine Verbindung mit einem bestimmten Host herzustellen, und die Funktion gibt einen int-Wert zurück,-1bedeutet Fehler * der erste Parameter ist der Socket, den die socket-Funktion erstellt hat, der diese Socket an die angegebene Host-Adresse verbinden soll * der zweite Parameter ist die Host-Adresse und der Portnummer, die der Socket sock verbinden möchte * der dritte Parameter ist die Größe der Host-Adresse */ int con = connect(sock, (struct sockaddr *) &socketPram, sizeof(socketPram)); if(con == -1{ close(sock); NSLog(@"Verbindung fehlgeschlagen"); return; } NSLog("Verbindung erfolgreich"); // Ankunft hier bedeutet eine erfolgreiche Verbindung.
4Nachdem die Verbindung erfolgreich hergestellt wurde, können Sie Daten senden und empfangen.
- (IBAction)senddata:(id)sender { // Daten senden char sendData[32] = "hello service"; ssize_t size_t = send(self.sock, sendData, strlen(sendData), 0); NSLog(@"%zd",size_t); } - (void)recvData{ // Daten empfangen, in einem Unterthread speichern 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; } } }
Nun ist es so weit, dass wir mit socket lokale Kommunikation zwischen zwei Apps herstellen. Dies ist mein erster Blogbeitrag. Einerseits möchte ich meine Erfahrungen festhalten, andererseits möchte ich mit Ihnen teilen. Falls es in dem Artikel Unkorrektes gibt, freuen wir uns über Ihre Korrekturen. Am Ende des Artikels finden Sie die Adresse des Demos. Zwei Projekte, diejenigen, die daran interessiert sind, können sie herunterladen und ausprobieren.
https://pan.baidu.com/s/1nvcvC8p
Dies ist die Zusammenfassung der Informationen zur Kommunikation zwischen iOS-Apps - local socket. Weitere Informationen werden nach und nach hinzugefügt. Vielen Dank für die Unterstützung unseres Forums!
Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem Urheber. Der Inhalt wurde von Internetbenutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine rechtlichen Haftung. Wenn Sie Inhalte finden, die möglicherweise urheberrechtlich geschützt sind, senden Sie bitte eine E-Mail an: notice#oldtoolbag.com (bei der E-Mail senden Sie bitte # durch @ ersetzen) und geben Sie relevante Beweise an. Sobald nachgewiesen wird, dass die Inhalte urheberrechtlich geschützt sind, wird diese Website die fraglichen Inhalte sofort löschen.