2

我有一个需要在网络上运行的简单乒乓球游戏,服务器将创建一个包含球和 2 个球棒位置的游戏,当客户端连接到服务器时,服务器将创建一个名为 PongPlayerThread 的新类,它将处理与客户端到服务器的输入和输出流,

我的服务器工作 100% 正常,没有任何数据从客户端到服务器,服务器可以毫无问题地向客户端发送信息,但我有一个奇怪的问题,但首先这是我的代码,所以你可以看到我有什么。

乒乓服务器

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

这是我的 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");
    }*/

}

这是我的 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();
}

现在当我运行我的服务器时它很好,然后我连接一个客户端,当客户端连接时乒乓球应该在等待另一个玩家时静止不动,但是一旦我关闭,球只会自行更新而不从服务器获取数据客户端程序,我的服务器会出现这个错误

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)

PongPlayerThread 中的第 42 行是这个

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

这几天我一直在尝试解决这个问题,但我仍然没有找到解决方案,我觉得输入流无法连接到客户端的输出流,我曾尝试使用wireShark但这是一个局域网程序,所以它不会t 工作,wireShark 中不会显示任何内容。如果有人能对此有所启发,将不胜感激。

帆布

iTech 更新 好的,我在这里使用了你的代码,现在是我的 PongPlayerThread 中的内容

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();
    }

这将在控制台中显示“客户端发送:你好”,但我的客户端不会停止并继续从服务器接收数据,

如果我将您给我的 if 语句放入具有 out.println(pongData) 的 while 语句中,它可以工作,但是一旦客户端连接和断开连接,我就会收到错误消息,或者如果两个客户端连接然后他们都离开我会收到错误消息再次收到此错误:(

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)

第 45 行是

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

将代码整理出来,但现在在我的 pongClient 代码中

 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");
        }

    }

一旦碰到这个,它就不会做任何事情,并且会再次导致整个错误。

我发现了错误,我放的地方

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

如果再放 line = in.readLine() 会报错。奇怪,但现在已经修复了,数据可以从客户端发送到服务器,服务器到客户端:)

4

2 回答 2

0

一旦客户端连接到您的服务器,if ((line = in.readLine()) == null)它将阻塞线程,直到收到来自客户端的消息。

建立连接后,您需要从客户端发送一些东西

PongPlayerThread您可以修改以下内容并删除该else

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

PongClient建立socket连接后,您可以发送一些消息,例如serverOut.println("Hello");

于 2013-02-16T19:39:06.883 回答
0

“连接重置”有多种原因,但最常见的原因是您写入了已被另一端关闭的连接。换句话说,应用程序协议错误。

于 2013-02-17T00:20:58.183 回答