2010-03-03 20 views
0

Je travaille actuellement sur un serveur proxy simple, qui reçoit une requête http du navigateur, le traite, puis le transmet au serveur web désiré.Java socket programming - stream get bloqué

J'essaie d'obtenir la requête du flux d'entrée de la socket connectée par le navigateur, tout va bien sauf que le flux reste bloqué après avoir reçu le dernier bloc de données.

Mon code est en fait très simple, comme le montre ci-dessous:

ServerSocket servSocket = new ServerSocket(8282); 
Socket workSocket = servSocket.accept(); 
InputStream inStream = workSocket.getInputStream(); 
byte[] buffer = new byte[1024]; 
int numberRead = 0; 

while ((numberRead = inStream.read(buffer, 0, 1024)) != -1){ 
System.out.println(new String(buffer)); 
} 

La boucle ne peut tout simplement pas sortir, même la réception de la demande est terminée.

Existe-t-il une méthode pour contourner ce problème?

Merci d'avance pour tout conseil.

+0

vous devez fournir les détails, et probablement aussi le code source, pour nous permettre de trouver le problème. –

+0

Le code ajouté, s'il vous plaît avis. –

+0

Pourquoi ne pas simplement configurer Apache HTTPD et mod_proxy? – pjp

Répondre

0

Il fonctionnera jusqu'à ce que la connexion soit fermée, et le client attend probablement une réponse HTTP de votre part et ne la ferme pas.

+0

Dans ce cas, il semble que je n'ai aucun moyen de gérer la demande, sauf en utilisant des discussions? –

+0

Eh bien, vous pouvez utiliser la lecture/écriture sélective et non bloquante - un thread fera dans ce cas. Je ne suis pas un expert Java et je ne peux pas vous donner plus de détails. –

1

Comme dans InputStream javadoc la méthode bloquera jusqu'à ce que les données soient disponibles ou que l'EOF soit rencontré. Donc, l'autre côté de Socket doit le fermer - alors l'appel inStream.read() retournera.

Une autre méthode consiste à envoyer la taille du message que vous voulez lire en premier, afin que vous sachiez à l'avance combien d'octets vous devez lire. Ou vous pouvez utiliser BufferedReader pour lire à partir du socket de manière linéaire. BufferedReader a une méthode readLine() qui retourne chaque fois qu'une ligne est lue, ce qui devrait fonctionner pour vous puisque les paquets de protocole HTTP sont symétriques et divisés en lignes.

+0

Cependant, le client se connectant à la socket est un navigateur, comme Firefox ou IE. Je n'ai aucun moyen de contrôler le navigateur, ni fermer le socket ni envoyer la taille du message au début. –

+0

Ok, donc je suggère d'utiliser BufferedReader.Chaque paquet HTTP est délimité par une ligne, donc vous allez lire quelques lignes et être capable de dire si c'est tout le paquet (ça finira toujours par newline). – pajton

+0

J'ai essayé l'approche BufferedReader, mais le flux reste bloqué. –

0

Le navigateur attend une réponse avant de fermer la connexion. D'autre part, votre méthode de lecture se bloque jusqu'à ce que le flux/la connexion soit fermé ou que de nouvelles données soient reçues.

0

Ce n'est pas une solution directe selon votre code actuel. Comme HTTP est un protocole basé sur une ligne, vous pouvez utiliser un Buffered Reader et appeler le readLine().

+0

J'ai essayé l'approche BufferedReader, mais le flux reste bloqué. –

0

Le lorsqu'une demande HTTP est en elle sera toujours être conclu avec une ligne blanche, par exemple:

GET /someFile.html HTTP/1.1 
Host: www.asdf.com 

Après l'envoi de cette demande la connexion client sera alors attendre une réponse du serveur avant Fermeture de la connexion. Donc, si vous voulez analyser la requête de l'utilisateur, il vaut mieux utiliser un BufferedReader et lire des lignes entières jusqu'à ce que vous atteigniez une ligne vide.