2016-08-06 56 views
0

Ich kann nicht mit einer Chrome App arbeiten, um Daten über TCP-Verbindung vom Server zu empfangen. Ich bekomme kein onReceived-Ereignis. Es funktioniert nur das zweite Mal, aber nicht das erste Mal. Ich habe alles aus der Dokumentation kopiert, aber der Code funktioniert einfach nicht und ich habe keine Ahnung, was falsch ist. Ich kann sehen, dass meine 'ABCDEFGHI'-Zeichenfolge vom Server im tcpdump-Fenster gesendet wird, aber aus irgendeinem Grund bekommt Chrome sie nicht. Der Fehler in diesem Beispiel ist vollständig reproduzierbar. Hier sind die Dateien:Chrome App empfangen (TCP) Daten aus dem Netzwerk Beispiel schlägt fehl

DIE APP

[[email protected] nettest]$ ls -l 
total 16 
-rw-rw-r-- 1 niko niko 174 Aug 6 16:10 background.js 
-rw-rw-r-- 1 niko niko 208 Aug 6 16:11 main.html 
-rw-rw-r-- 1 niko niko 928 Aug 6 16:54 main.js 
-rw-rw-r-- 1 niko niko 281 Aug 6 16:10 manifest.json 
[[email protected] nettest]$ 

manifest.json:

[[email protected] nettest]$ cat manifest.json 
{ 
    "name": "Receive Test", 
    "description": "Network receive test App.", 
    "version": "0.1", 
    "manifest_version": 2, 
    "app": { 
    "background": { 
     "scripts": ["background.js"] 
    } 
    }, 
    "icons": { 
    }, 

    "sockets": { 
     "tcp" : { 
       "connect": ["*"] 
     } 
    } 
} 
[[email protected] nettest]$ 

background.js:

[[email protected] nettest]$ cat background.js 
chrome.app.runtime.onLaunched.addListener(function() { 
    chrome.app.window.create('main.html', { 
    'outerBounds': { 
     'width': 400, 
     'height': 500 
    } 
    }); 
}); 
[[email protected] nettest]$ 

main.html:

[[email protected] nettest]$ cat main.html 
<!DOCTYPE html> 
<html> 
    <head> 
    <script type="text/javascript" src="/main.js"></script> 
    </head> 
    <body> 
    <div>Networking test app</div> 
    <a href="" id="connect_btn">conect</a> 
    </body> 
</html> 

[[email protected] nettest]$ 

main.js:

[[email protected] nettest]$ cat main.js 
var socket; 
window.addEventListener("load",init); 
function init() { 
    var el; 
    el=document.getElementById('connect_btn'); 
    if (el!=null) el.addEventListener("click",connect_click); 
} 
function connect_click(event) { 

    event.preventDefault(); 

    chrome.sockets.tcp.create({}, function(createInfo) { 
     socket=createInfo.socketId; 
     chrome.sockets.tcp.setPaused(socket, false); 
     chrome.sockets.tcp.connect(socket,"localhost", 4433, connect_callback); 
    }); 
} 
function connect_callback(info) { 

    console.log("connection accepted: "+info); 
    chrome.sockets.tcp.setPaused(socket, false); 
    chrome.sockets.tcp.onReceiveError.addListener(receive_error); 
    chrome.sockets.tcp.onReceive.addListener(data_received); 

} 
function data_received(info) { 
    console.log("the data has been received:"); 
    console.log(info); 
} 
function receive_error(info) { 
    console.log("receive error"); 
    console.log(info); 
} 

[[email protected] nettest]$ 

SERVER CODE:

[[email protected] src]$ cat server.c 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netinet/tcp.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/types.h> 

int main(int argc, char *argv[]) 
{ 
    int flag=1; 
    int listenfd = 0, connfd = 0; 
    struct sockaddr_in serv_addr; 

    char data[10] = {'A','B','C','D','E','F','G','H','I','\n'}; 
    int result; 

    listenfd = socket(AF_INET, SOCK_STREAM, 0); 
    memset(&serv_addr, '0', sizeof(serv_addr)); 

    result = setsockopt(listenfd,IPPROTO_TCP,TCP_NODELAY,(char *) &flag, sizeof(int)); 
    if (result<0) { 
     printf("result=%d\n",result); 
     return (1); 
    } 

    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 
    serv_addr.sin_port = htons(4433); 

    bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); 

    listen(listenfd, 10); 

    while(1) 
    { 
     connfd = accept(listenfd, (struct sockaddr*)NULL, NULL); 
     result = setsockopt(connfd,IPPROTO_TCP,TCP_NODELAY,(char *) &flag, sizeof(int)); 
     if (result<0) { 
      printf("result=%d\n",result); 
      return (1); 
     } 
     printf("connection accepted, sending data\n"); 
     write(connfd, &data, sizeof(data)); 
     sleep(5); 

     close(connfd); 
     printf("connection closed\n"); 
     sleep(1); 
    } 
} 
[[email protected] src]$ 

Wenn ich den Code dieses ausgeführt ist die Ausgabe:

connection accepted: 0 
main.js:31 receive error 
main.js:32 Object {resultCode: -100, socketId: 18} 
main.js:20 connection accepted: 0 
main.js:27 the data has been received: 
main.js:28 Object {data: ArrayBuffer, socketId: 19} 
main.js:27 the data has been received: 
main.js:28 Object {data: ArrayBuffer, socketId: 19} 
main.js:31 receive error 
main.js:32 Object {resultCode: -100, socketId: 19} 

Alle Ideen, was falsch sein könnte?

+0

Ich habe festgestellt, dass das Hinzufügen eines Schlafs (1) nach accept() syscall auf dem Server.c funktioniert. Dies ist jedoch für mich nicht nutzbar, das kostet viel Zeit. – Nulik

Antwort

0

Ich fand was falsch war. Der onReceived-Handler muss sofort nach der Socket-Erstellung registriert werden. Andernfalls geschieht Folgendes: Client sendet SYN, aber der Server antwortet mit ACK + -Daten. Wenn Chrome dieses Paket erhält, verfügt es noch nicht über den onReceived-Handler, sodass Daten im ersten Paket verloren gehen. Die Funktion connect_click() muss folgendermaßen umgeschrieben werden: