Java Client to Server Unknown Source

2019-07-22 13:25发布

问题:

I have a simple pong game that needs to work over a network, the server will create a game with the positions of the ball and 2 bats, when a client connects to the server, the server will create a new class known PongPlayerThread which will deal with the input and output streams of the client to server,

My server works 100% fine without any data from the client to the server, the server can send information to the client without any problems, but I have a strange problem, But first here is my code, so you can see what I have.

PongServer

try
{
    serverSocket = new ServerSocket(port);
    listen = true;
    System.out.println("Server was setup and will try to create a socket");
}
catch(IOException e)
{
    System.err.println("Could not listen on port:" + port);
    System.exit(1);
}

while(listen)
{
    players[idPlayer] = new PongPlayerThread(serverSocket.accept(), idPlayer, rtnInfo());
    players[idPlayer].start();
    System.out.println("Client Connected with ID:" + idPlayer);
    players[0].passData(rtnInfo());
    idPlayer++;     
    if(idPlayer > 1)
    {
        listen = false;
        playing = true;
    }
}

while(playing)
{
    players[0].passData(rtnInfo());
    players[0].sleep(25);
    players[1].passData(rtnInfo());
    players[1].sleep(25);
}

....//more, but not important

Here is my PongClient

try
{
    socket = new Socket(host, port);
    serverOut = new PrintWriter(socket.getOutputStream(), true);
    serverInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (UnknownHostException e)
{
    System.err.println("Couold not connect to host:" + host);
    System.exit(1);
}
catch (IOException e)
{
    System.err.println("Could not get Input/Output from server");
    System.exit(1);
}

...

while ((pos = serverInput.readLine()) != null) 
{
    String text = "nothing";
    serverOut.println(text);
    String[] posValues = pos.split(":");
        model.getBall().setX(Double.parseDouble(posValues[0]));
        model.getBall().setY(Double.parseDouble(posValues[1]));


    /*if(PongController.moveUp == true)
    {
        System.out.println("Up");
        serverOut.println("up");
        PongController.moveUp = false;
    }
    else
    {
        serverOut.println("nothing");
    }*/

}

Here is my PongPlayerThread

try
{
    PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
        new InputStreamReader(
        socket.getInputStream()));

    String text = "hhh";

    System.out.println(in.toString());
    //System.out.println(text = in.readLine());
    System.out.println("Checking readLine value");

    String line; 
    if ((line = in.readLine()) == null) 
    { 
        System.out.println("A ok"); 
    } 
    else 
    { 
        System.out.println(":" + line); 
    }

    while(send)
    {
        //String temp = in.readLine();
        //if(temp.equals("up"))
        //{
        //        System.out.println("Up you say");
        //}
        out.println(pongData);
    }

    out.close();
    in.close();
    socket.close();
}

catch (IOException e) 
{
    e.printStackTrace();
}

Now when I run my server it is fine, I then connect a client, when a client connects the pong ball should sit still while it waits for another player, but the ball will just update itself without getting data from the server, once I close the clients program, my server will come up with this error

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Pong.PongPlayerThread.run(PongPlayerThread.java:42)

The line 42 in PongPlayerThread is this

if ((line = in.readLine()) == null) 

I have been trying to fix this for days, but I have still not found the solution, I feel like the inputStream cannot connect to the outputStream of the client, I have tried to use wireShark but this is a LAN program, so it won't work and nothing will show up in wireShark. If anyone could shine some light onto this, It would be much appreciated.

Canvas

iTech update Ok I have used your code here is what is in my PongPlayerThread now

public void run()
{
    try
    {
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                    new InputStreamReader(
                    socket.getInputStream()));

        String text = "hhh";

        System.out.println(in.toString());
        //System.out.println(text = in.readLine());
         System.out.println("Checking readLine value");

         String line = null; 
         if ((line = in.readLine()) != null) // why you check if it is null !?
         { 
             System.out.println("Client sent: "+line); 
         } 

        while(send)
        {
            out.println(pongData);
        }

         out.close();
         in.close();
         socket.close();
    }

this will say in console "Client sent: Hello", but my client will not stop and keep taking in data from the server,

If i put the if statement you gave me into the while statement which has out.println(pongData) it works but I get a error once a client connects and disconnects, or i get a error if two clients connect and then they both leave i get this error again :(

java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
at sun.nio.cs.StreamDecoder.read(Unknown Source)
at java.io.InputStreamReader.read(Unknown Source)
at java.io.BufferedReader.fill(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at java.io.BufferedReader.readLine(Unknown Source)
at Pong.PongPlayerThread.run(PongPlayerThread.java:45)

and line 45 is

if ((line = in.readLine()) != null) // why you check if it is null !?

Sorted the code out, but now in my pongClient code

 while ((pos = serverInput.readLine()) != null) 
    {
        String text = "nothing";
        serverOut.println(text);
        String[] posValues = pos.split(":");
        model.getBall().setX(Double.parseDouble(posValues[0]));
        model.getBall().setY(Double.parseDouble(posValues[1]));


        if(PongController.moveUp == true)
        {
            System.out.println("Up");
            serverOut.println("up");
            PongController.moveUp = false;
        }
        else
        {
            serverOut.println("nothing");
        }

    }

Once it hits this, it wont do anything, and will cause the whole error again.

I found the error, where i had put

 if ((line = in.readLine()) != null)
             { 

if you put line = in.readLine() again, it will cause an error. strange, but it is fixed now, and data can be sent from the client to server, and server to client :)

回答1:

Once a client connects to your server the if ((line = in.readLine()) == null) will block the thread until a message is received from the client.

You need to send something from the client after the connection is established

In PongPlayerThread you can modify the following and remove the else block

String line = null; 
if ((line = in.readLine()) != null) // why you check if it is null !?
{ 
    System.out.println("Client sent: "+line); 
} 

In PongClient after establishing the socket connection, you can send some message, e.g. serverOut.println("Hello");



回答2:

'Connection reset' has several causes, but the most common one is that you have written to a connection that had already been closed by the other end. In other words, an application protocol error.