Gå til innhold

[Løst] Socket, ObjectOutput/InputStream, Connection Reset


Anbefalte innlegg

Jeg jobber med å skrive en server/client som sender og mottar javaobjecter over en tcpsocket (det er en del av et bachelorprosjekt).

Sending og mottak går fint, men når jeg prøver å behandle en feilsituasjon på serveren, så får clienten en feil.

 

I testklienten sender jeg først en enum for å indikere at jeg vil logge inn, så sender jeg to stringer med brukernavn og passord.

 

Slik jeg hadde tenkt å behandle feilsituasjonen (og som oppstår akkurat nå fordi sjekking av brukernavn og passord ikke er implementert) er å sende en ENUM tilbake for å indikere en feilsituasjon, og så sende en string med en feilmelding.

 

Situasjon 1 (funker): Jeg leser først enum VERIFY_LOGIN fra klienten, og så leser jeg ut to strenger (user/pass). Deretter sender jeg feilmeldingen (som beskrevet) tilbake.

 

Situasjon 2 (funker ikke): Jeg leser enum VERIFY_LOGIN fra klienten, og så sender jeg feilmeldingen (som beskrevet) tilbake. I dette tilfellet får clienten "Connection reset"

 

Er dette "riktig", eller gjør jeg noe feil ? I dette tilfellet får jeg det til å funke fordi jeg vet akkurat hva klienten sender, men hva om jeg ønsker å sende en ERROR dersom jeg får garbage - da vil jeg helst at klienten skal få feilmeldingen, og ikke bare blir frakoblet.

 

Edit: Ok, jeg skjønner nå at jeg får "Connection reset" fordi clienten forsøker å skrive til en socket som serveren har stengt, men jeg klarer fortsatt ikke å lese objectene serveren har sendt fra ObjectInputstreamen etter at jeg har fått det exceptionet.

 

(Test)Klient

 

 

package no.hig.rag;
import java.io.*;
import java.net.*;

public class RagServerTester extends Utils {
public static void main(String[] a) {
		i("Missing hostname from command line, using \"localhost\"");
		new HeloTest("localhost");
		new LoginTest("localhost");
}
class HeloTest extends Utils {
HeloTest(String host) {
	i("Start of HeloTest");

	ObjectOutputStream oos = null;
	ObjectInputStream ois = null;
	Socket socket = null;
	try {

		socket = new Socket(host, 1149);
		oos = new ObjectOutputStream(socket.getOutputStream());
		ois = new ObjectInputStream(socket.getInputStream());

		oos.writeObject(Const.command.HELO_EHLO);
		i("Sending \"helo\"");
		oos.writeObject(new String("helo"));
		Const.response responseCode = (Const.response)ois.readObject();
		if(responseCode.equals(Const.response.OK)) {
			String response = (String)ois.readObject();
			if(response.equals("oleh")) {
				i("Got \"oleh\" back");
				i("HeloTest sucseeded.");

			} else {
				e("Got \"" + response + "\"");
				i("HeloTest failed.");
			}
		}
		i("");
		oos.close();
		ois.close();
		socket.close();
	} catch(Exception e) {
		System.out.println(e.getMessage());
	}
}
}

class LoginTest extends Utils {
LoginTest(String host) {
	i("Start of LoginTest");

	ObjectOutputStream oos = null;
	ObjectInputStream ois = null;
	Socket socket = null;

	try {
		socket = new Socket(host, 1149);

		oos = new ObjectOutputStream(socket.getOutputStream());
		ois = new ObjectInputStream(socket.getInputStream());

		i("Sending \"username\" and password test1");

		oos.writeObject(Const.command.VERIFY_LOGIN);
		oos.writeObject(new String("username"));
		oos.writeObject(new String("test1"));
		i("Wrote logindata");

		Const.response responseCode = (Const.response)ois.readObject();
		i("Read responsecode");
		if(responseCode.equals(Const.response.OK)) {
			i("Login OK");
		} else {
			e("Got eeerror");
			String response = (String)ois.readObject();
			e(response);
		}

		oos.close();
		ois.close();
		socket.close();
	}catch (SocketException e1) {
		//e1.printStackTrace();
		e("Got SocketException: " + e1.getMessage());
		e1.printStackTrace();
	} catch (UnknownHostException e1) {
		e1.printStackTrace();
	} catch (IOException e1) {
		e1.printStackTrace();
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
}
}

class Const {
enum response { ERROR, OK, LOGIN_OK, LOGIN_ERROR }
enum command { INVALID, HELO_EHLO, VERIFY_LOGIN }
}

 

Log / stacktrace

 

0 [main] INFO no.hig.rag.RagServerTester - Missing hostname from command line, using "localhost"
1 [main] INFO no.hig.rag.RagServerTester - Start of HeloTest
18 [main] INFO no.hig.rag.RagServerTester - Sending "helo"
61 [main] INFO no.hig.rag.RagServerTester - Got "oleh" back
61 [main] INFO no.hig.rag.RagServerTester - HeloTest sucseeded.
61 [main] INFO no.hig.rag.RagServerTester - 
63 [main] INFO no.hig.rag.RagServerTester - Start of LoginTest
64 [main] INFO no.hig.rag.RagServerTester - Sending "username" and password test1
64 [main] INFO no.hig.rag.RagServerTester - Wrote logindata
104 [main] ERROR no.hig.rag.RagServerTester - Got SocketException: Connection reset
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at java.net.SocketInputStream.read(SocketInputStream.java:182)
at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2248)
at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(ObjectInputStream.java:2428)
at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2498)
at java.io.ObjectInputStream$BlockDataInputStream.skipBlockData(ObjectInputStream.java:2400)
at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1896)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1580)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1685)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1325)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at no.hig.rag.LoginTest.<init>(RagServerTester.java:101)
at no.hig.rag.RagServerTester.main(RagServerTester.java:23)

 

 

Server (sockethandeler)

 

package no.hig.rag.handlers;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import no.hig.rag.Utils;
import com.jolbox.bonecp.BoneCP;
import no.hig.rag.Const;
import no.hig.rag.framework.RequestHandler;

public class OOSHandeler extends Utils implements RequestHandler  {
@Override
public void handleRequest(Socket socket, BoneCP connectionPool) {
	ObjectOutputStream oos;
	ObjectInputStream ois;
	try {

		oos = new ObjectOutputStream(socket.getOutputStream());
		ois = new ObjectInputStream(socket.getInputStream());

		Const.command command;
		try {
			command = (Const.command)ois.readObject();
		} catch (ClassNotFoundException e) {
			command = Const.command.INVALID;
		}

		switch(command) {
		case HELO_EHLO:
			try {
				i("Got HELO_EHLO");
				String helo = (String)ois.readObject();
				oos.writeObject(Const.response.OK);
				oos.writeObject(
						new StringBuffer(helo).reverse().toString());
			} catch (ClassNotFoundException e) {
				oos.writeObject(Const.response.ERROR);
				oos.writeObject(
						new String("HELO_EHLO expects a String sendt as argument"));
			}

			break;

		case VERIFY_LOGIN:
			i("Got VERIFY_LOGIN");
			i("Sending error");
			oos.writeObject(Const.response.ERROR);
			i("Sending error message");
			oos.writeObject(
					new String("Verifying of logins are not supported."));
			oos.flush();
			break;
		case INVALID:
		default:
			i("Got INVALID");
			oos.writeObject(Const.response.ERROR);
			oos.writeObject(
					new String("I did not understand your command," +
							" or something was wrong."));
			break;
		}

		oos.flush();
		oos.close();
		ois.close();

	} catch (IOException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}

}

}

 

Endret av Kagee
Lenke til kommentar
  • 2 uker senere...
Videoannonse
Annonse

Jeg merket tråden som løst, siden vi redesignet bruksområdet til serveren gikk over til 10 php-filer.

 

Men - er det det at klienten ikke mottar meldingene før den mottar en socket-close-melding, eller er det det at klienten bare nekter å lese fra en lukket socket ?

Lenke til kommentar

Jeg merket tråden som løst, siden vi redesignet bruksområdet til serveren gikk over til 10 php-filer.

 

Men - er det det at klienten ikke mottar meldingene før den mottar en socket-close-melding, eller er det det at klienten bare nekter å lese fra en lukket socket ?

Veldig godt spørsmål. Jeg kjenner ikke den interne implementasjonen av socketen, men jeg tipper at så snart en socket close blir detektert av TCP/IP, så stenges InputStream og OutputStream umiddelbart. En stengt InputStream kan man ikke lese fra. Det er teoretisk mulig at socket close kommer an før meldingene, men jeg tipper at socket close er rett og slett kjappere enn din leserutine. Mye gjetting her blush.gif

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...