Prise de ne pas fermer les serverside lors de l'appel de socket.close() en JAVA cliente
Je vais avoir des problèmes avec des sockets en java. J'ai un ServerSocket
qui est à l'écoute avec accept() et engendre des threads pour chaque client demande. La Communication entre les clients et le serveur fonctionne très bien. Je suis en utilisant un inputstream pour lire les données de vos clients dans la serverthreads, comme:
inputStream = mySocket.getInputStream();
bytes = inputStream.read(buffer);
Mon problème est que si je l'appelle socket.close() de la part des clients, il ne se passe rien à l'appel de blocage de bytes = inputStream.read(buffer);
, il continue à bloquer. Mais il fonctionne si je ferme la socket du serveur, puis le inputStream.read(buffer);
de la client retourne la valeur "-1".
SERVEUR MAINTHREAD:
//SERVER MAIN THREAD, SPAWNS CLIENT THREADS
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (listening){
new ServerThread(serverSocket.accept(), monitor).start();
}
SERVEUR CLIENTTHREADS:
public class ServerThread extends Thread{
public ServerThread(Socket socket, Monitor monitor) {
this.socket = socket;
this.monitor = monitor;
}
public void run(){
byte[] buffer = new byte[1024];
int bytes;
//Listen
while(true){
try {
InputStream inputStream = socket.getInputStream();
monitor.doStuffWithOtherThreads(Object myObject);
bytes = inputStream.read(buffer); //Problem
if (bytes == -1){
System.out.println("breaks");
break;
}
byte[] readBuf = (byte[]) buffer;
String readMessage = new String(readBuf, 0, bytes);
System.out.println(readMessage);
System.out.println(bytes);
} catch (IOException e) {
System.out.println("Connection closed");
break;
}
}
}
CLIENT:
InetAddress serverAddr = InetAddress.getByName("serverhostname");
socket = new Socket(serverAddr, PORT);
socket.close(); //Close the socket connection from client. Nothing happens in the serverthread
Mis à jour avec des exemples de code. Et oui j'ai vérifier -1 explicitement. Le thread encore des blocs à lire();
Une solution simple est de demander au client d'envoyer un "déconnexion" message juste avant l'appel de
close()
, et le serveur de sortir de la boucle lorsque ce message est reçu.Oui, j'ai pensé à ce sujet. Mais ce n'est pas la meilleure solution, peut-être.
Votre exemple de code ne vérifie pas pour -1. Donc, soit c'est encore le problème ou qui n'est pas le vrai code, auquel cas vous avez encore besoin d'afficher le code réel.
OriginalL'auteur James Ford | 2010-07-21
Vous devez vous connecter pour publier un commentaire.
Le serveur de code que vous avez posté ne pas vérifier -1. Donc, soit c'est le problème ou qui n'est pas le vrai code, auquel cas vous devriez poster le réel code pour le commentaire.
MODIFIER Le code que vous avez posté ne se comporte pas comme vous l'avez décrit.
Votre code fonctionne pour moi. Et la fermeture d'un socket créé par la même JVM qui est bloqué dans un read() ne cause pas que read() renvoie -1, il provoque une IOException.
Bizarre. Il ne fonctionne pas pour moi. Je suis la fermeture de la socket avec un appareil android. C'est peut-être le problème? Je vais essayer de vous connecter et fermer() avec un ordinateur.
Ne sais rien à propos de Android mais la fermeture de la socket doit envoyer un paquet TCP FIN qui est reçu comme EOS par les pairs. Si ce n'est que c'est un bug. Pouvez-vous renifler le réseau? Que serait-être ma prochaine étape. Mais je suis inquiet au sujet de votre déclaration de clôture au serveur, le serveur de lecture)) méthode renvoie -1. Il n'a pas. Sont youmsure vous avez vu ça? Je me demandais si vous utilisez le code que vous pensez que vous êtes en cours d'exécution.
Ce que j'essaie de dire c'est que si je ferme la socket server-side. La méthode read() dans le client(Oui, j'ai un client) renvoie -1 comme il se doit.
OriginalL'auteur user207421
Je ne sais pas si j'ai bien compris votre question, mais je dirais que c'est normal que c'est le serveur de fermer le socket.
Sur le côté serveur (dans un thread indépendant), vous avez la socket d'écoute :
Alors probablement (dans le même thread si c'est un petit serveur) une boucle d'accepter des connexions entrantes (pas de gestion des exceptions, probablement le socket.à proximité se trouve dans un bloc finally) :
Sur le côté client, vous avez :
Le serveur doit savoir quand il a atteint la fin de la demande. Par exemple en http, il pourrait être (prises à partir d'un mockHttpServer en scala, alors il pourrait y avoir quelques erreurs, mais le processus est le même):
EDIT :
J'ai lu le code ajouté et je ne comprends toujours pas :
Vous avez 3 "sockets" :
Le serveur d'ouvrir et de fermer l'écoute et "accepter" socket, et ne devrait pas avoir d'impact de la mauvaise socket client de gestion.
Alors si vous voulez que votre serveur pour accepter plusieurs connexions simultanées, vous pouvez ajouter un pool de threads pour accepter des connexions et le traitement des demandes et des réponses.
L'Ofc Socket n'est pas statique? C'était juste un exemple. Ses pas comme j'essaie de l'appeler de cette façon à mes clients. Ce n'est pas comme j'ai posté mon code réel. J'ai juste essayé de me faire comprendre. La seule question est "pourquoi ne pas InputStream.read() relâchez-le lorsque le support se trouve à proximité client.
Il n'est pas normal que c'est le serveur de fermer le socket'. La situation est totalement symétrique. La fin peut se fermer, et l'autre extrémité, puis obtient -1 ou null ou EOFException, selon la méthode qu'il appelle.
ok, mais j'ai été confus au sujet de la socket est fermée. Maintenant c'est plus clair. J'ai couru votre code sur ma machine (Ubuntu 9.10) avec java 1.5.0.20 et il n'est pas bloquant. Je vois des "pauses" à chaque connexion client.
c'est vrai que c'est symétrique, mais c'est mieux si le serveur ne s'appuient pas sur les clients de la fermeture de la sockets.
OriginalL'auteur Bruno Thomas
Essayer dans votre Android code client :
Il devrait être mieux 😉
OriginalL'auteur openkwaky