java - 有人可以帮助我加快 Java 网络代码的速度吗?

标签 java client client-server

好吧,我正在开发一款游戏(甚至还不是 alpha),它应该是一款 1 对 1 的格斗游戏,其中一个人托管服务器,另一个人连接。但现在代码太滞后,无法执行任何操作。有人可以看一下并告诉我如何加快速度吗? PS:我也在使用 Slick2D 库。

服务器:

import java.net.*;
import java.io.*;

public class SlickServer{
    public static void main(String[] args) throws IOException {

        int MAX_PLAYERS = 3;
        int playerNum = 0;
        Player[] players = new Player[MAX_PLAYERS];
        players[0] = new Player(25,25);
        players[1] = new Player(125,125);
        players[2] = new Player(225,225);
        ServerSocket serverSocket = new ServerSocket(4444);
        boolean listening = true;

        while(listening){
            System.out.println("Waiting to connect with: " + playerNum);
            new ClientThread(serverSocket.accept(), players, playerNum).start();
            //stops here.
            System.out.println("Connected with: " + playerNum + " Now incrementing");
            playerNum++;
            System.out.println("Incremented to: " + playerNum);
        }



        serverSocket.close();
        System.exit(0);
    }
}

服务器线程:

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.*;
import java.io.*;

public class ClientThread extends Thread implements Runnable{
    Socket acceptedSocket;
    Player[] players;
    int playerNum;

    public ClientThread(Socket acceptedSocket, Player[] players, int playerNum){
        super("ClientThread");
        this.acceptedSocket = acceptedSocket;
        this.players = players;
        this.playerNum = playerNum;
    }

    public void run(){
        try{

            Socket clientSocket = acceptedSocket;
            System.out.println("Accepted. Now creating I/O.");
            ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
            ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
            System.out.println("I/O with: " + playerNum + " working.");
            out.writeInt(playerNum);
            out.flush();

            while(true){
                if(playerNum == 0){
                    players[0].x = in.readInt();
                    players[0].y = in.readInt();
                    out.writeInt(players[1].x);
                    out.writeInt(players[1].y);
                    out.flush();
                }

                else if(playerNum == 1){
                    players[1].x = in.readInt();
                    players[1].y = in.readInt();
                    out.writeInt(players[0].x);
                    out.writeInt(players[0].y);
                    out.flush();
                }

                else if(playerNum == 2){
                    players[2].x = in.readInt();
                    players[2].y = in.readInt();
                    out.writeInt(players[0].x);
                    out.writeInt(players[0].y);
                    out.flush();
                }
            }

        }

        catch(Exception e){
            e.printStackTrace();
            System.exit(1);
        }


    }


}

客户:

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

import java.io.*;
import java.net.*;


public class SlickClient extends BasicGame{

    int MAX_PLAYERS = 3;
    int playerNum = 0;
    Player[] players;
    ClientThread ct;

    int serverDelay = 15;

    public SlickClient()
    {
        super("Client");
    }

    @Override
    public void init(GameContainer gc)
            throws SlickException {
        try{
            players = new Player[MAX_PLAYERS];
            players[0] = new Player(25,25);
            players[1] = new Player(125,125);

            ct = new ClientThread(players);
            ct.start();
            ct.setPriority(Thread.MAX_PRIORITY);

            playerNum = ct.playerNum;   
        }

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

    }

    @Override
    public void update(GameContainer gc, int delta)
            throws SlickException
    {
        Input input = gc.getInput();

        if(input.isKeyDown(Input.KEY_A))
        {
            players[playerNum].x-=5;
        }

        if(input.isKeyDown(Input.KEY_D))
        {
            players[playerNum].x+=5;
        }

        if(input.isKeyDown(Input.KEY_W))
        {
            players[playerNum].y-=5;
        }

        if(input.isKeyDown(Input.KEY_S))
        {
            players[playerNum].y+=5;
        }



    }

    public void render(GameContainer gc, Graphics g)
            throws SlickException
    {
        g.fillRect(players[0].x, players[0].y, 50, 50);
        g.fillRect(players[1].x, players[1].y, 50, 50);

    }

    public static void main(String[] args)
            throws SlickException
    {
         AppGameContainer app =
            new AppGameContainer( new SlickClient() );

         app.setAlwaysRender(true);
         app.setTargetFrameRate(30);
         app.setDisplayMode(800, 600, false);
         app.start();
    }
}

class ClientThread extends Thread implements Runnable{
    Socket socket;
    Player[] players;
    int playerNum;
    ObjectOutputStream out;
    ObjectInputStream in;

    public ClientThread(Player[] players){
        super("ClientThread");

        try{

            socket = new Socket("98.203.176.196", 4444);
            out = new ObjectOutputStream(socket.getOutputStream());
            in = new ObjectInputStream(socket.getInputStream());
            this.players = players;
            playerNum = in.readInt();
            System.out.println(playerNum);

        }

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

    public void run(){
        try{
            while(true){
                if(playerNum == 0){
                    try{
                        out.writeInt(players[0].x);
                        out.writeInt(players[0].y);
                        out.flush();
                        players[1].x = in.readInt();
                        players[1].y = in.readInt();
                    }

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

                else if(playerNum == 1){
                    try{
                        out.writeInt(players[1].x);
                        out.writeInt(players[1].y);
                        out.flush();
                        players[0].x = in.readInt();
                        players[0].y = in.readInt();
                    }

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

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

最佳答案

只有当客户端位于服务器的远程计算机上时才会出现延迟吗?如果是这样,并且您在两个盒子之间有一个很好的 ping 时间,那么我会大胆猜测并说您可能在这里遇到了 Nagle 的算法?您推送的数据非常小(writeInt)。

您可以尝试使用 BufferedOutputStream 中介,但如果您想尝试快速修复,您也可以尝试在套接字上禁用 Nagle。

Socket.setTcpNoDelay(true);

关于java - 有人可以帮助我加快 Java 网络代码的速度吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1925801/

相关文章:

java - 查找给定范围内的史密斯数

java - 字符串的 ArrayList 到一个字符串

java - Spring Boot 管理客户端无法构建

java - 服务器提供实时游戏状态更新

c - 识别 C 客户端/服务器程序中不同类型的客户端

java - 与 REST Web 服务设计相比,使用 Direct Web Remoting 有何优势?

java - 在 Spring MVC 中处理静态页面的良好实践

java - Spring @RequestScope 是否有 Micronaut 类似物?

c - 从套接字读取()每次都需要额外的输入(C编程远程shell)

c - 未知的段错误