12
votes

Socket Stream Stream est suspendu à la lecture finale. Meilleure façon de gérer cela?

Je suis un peu soulevé sur la façon d'éviter ma prise suspendue à la lecture. Voici mon code:

(Lots of data above this point)
57
10
37
37
69
79
70
10


3 commentaires

"SOMEMACHINE" ferme la prise après avoir envoyé le dernier octet? attend-il de répondre à une réponse / reconnaissance de le faire?


Dupliqué possible de Problème de blocage Java ....


Fixé dans mon cas lorsque j'ai ajouté, à la fin du côté serveur, socket.close () ou socket.shutdownoutput ()


6 Réponses :


0
votes

Essayez:

while ((result = in.read()) != null) {


2 commentaires

Cela ne compile pas comme in.Read () renvoie un int qui ne peut pas être comparé à null . Je pense que vous avez plutôt voulu dire tandis que ((résultat = in.readline ())! = Null) {, mais cela ne fonctionne pas non plus.


En outre, LIRE est un appel de blocage. Cela va accrocher le verrouillage de la bande de roulement. Si vous utilisez un multihreading, cela va enfermer un processeur



6
votes

Je pense que vous n'obtiendrez que -1 lorsque le serveur décide d'arrêter la conversation, c'est-à-dire ferme son flux de sortie ou ferme complètement la prise. Sinon, le ruisseau reste ouvert pour des données entrantes potentielles.


2 commentaires

Ah, bon point, n'avait pas pensé à cela. Cependant, cela me laisse toujours gratter ma tête sur la manière dont je sais que mon propre flux d'entrée est terminé.


C'est une question de définition de protocole. Quel type de données est échangé? Est-ce structuré? A-t-il un caractère final ou une séquence? At-il une longueur fixe?



13
votes

Le problème avec juste arrêtant où lire serait suspendu, c'est que cela peut se produire dans 2 cas:

1: le serveur n'a plus de données à envoyer

2: Le serveur a envoyé plus de données, mais votre client ne l'a pas encore reçu en raison de la surcharge du réseau.

Et vous voulez seulement arrêter de lire dans le premier cas, mais vous voulez lire de bloquer dans le second cas.

Le moyen de résoudre ce problème est de créer un protocole de transfert (standard) qui permet au serveur de dire au client la quantité de données qu'il attend d'envoyer.

Si le serveur connaît la taille totale des données à l'avance, commencez simplement à envoyer le nombre total d'octets dans le transfert, puis envoyez les données. De cette façon, le client sait quand il a reçu toutes les données.

(ou le serveur peut simplement fermer la connexion lorsque vous avez terminé. de cette façon lire devrait échouer, mais cela ne fonctionne que si vous n'avez pas besoin de la connexion à l'avenir)


1 commentaires

Oui, je pense que vous avez au cœur de cela. J'ai un en-tête de longueur de contenu, je peux tirer parti de laquelle je pense fonctionnera. Merci!



3
votes

Je ne suis pas un expert Android, mais cela semble fonctionner très bien sur Android:

    try {
        telnetClient = new Socket(server, port);
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    if (telnetClient.isConnected()) {
        try {
            InputStream instr = telnetClient.getInputStream();
            int buffSize = telnetClient.getReceiveBufferSize();
            if (buffSize > 0) {
                byte[] buff = new byte[buffSize];
                int ret_read = instr.read(buff);
                screen.append(new String(buff, 0, ret_read));
            }
        } catch (IOException e) {
            screen.append("Exception while reading socket:" + e.getMessage());
        }
    }


0 commentaires

2
votes

Je viens d'avoir ce même problème. Je l'ai résolu en définissant un délai d'attente juste après avoir créé l'objet de la prise ... socket.setsotimeout (10 * 1000);


0 commentaires

0
votes

J'ai trouvé que ce problème sera assez formidable. J'essayais d'exécuter une commande Windows Batch à partir de Java et le processus est suspendu à chaque fois que vous essayez de lire l'introuvable de la commande obtenue.

Je ne pouvais que régler cela inélégamment.

a) en recherchant une ligne spécifique que je connais signalerait la fin Informations utiles Formulaire le flux.
b) ou pour démarrer un nouveau fil que tue le processus à l'autre extrémité de la prise, dans ce cas pour moi iedriverserver.exe après un temps d'attente. xxx


0 commentaires