繁体   English   中英

客户端不起作用-服务器

[英]Does not work client - server

有问题,以下代码不起作用:

服务器

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    static ServerSocket serverSocket;
    static Socket socket;
    static DataOutputStream out;
    static DataInputStream in;
    static Users[] user = new Users[10];

    public static void main(String[] args) {
        try {
            System.out.println("Server Started...");
            serverSocket = new ServerSocket(7778);
            System.out.println("Server Start.");
            while (true) {
                socket = serverSocket.accept();
                for (int i = 0; i < 10; i++) {
                    if (user[i] == null) {
                        System.out.println("Conection from"
                                + socket.getInetAddress());
                        out = new DataOutputStream(socket.getOutputStream());
                        in = new DataInputStream(socket.getInputStream());

                        user[i] = new Users(out, in, user, i);
                        Thread thread = new Thread(user[i]);
                        thread.start();
                        break;
                    }
                }
            }

        } catch (IOException e) {

        }
    }
}

class Users implements Runnable {

    DataOutputStream out;
    DataInputStream in;
    Users[] user = new Users[10];
    String name;
    int playerid;
    int playeridln;
    int xin;
    int yin;

    public Users(DataOutputStream out, DataInputStream in, Users[] user, int pid) {
        this.out = out;
        this.in = in;
        this.user = user;
        this.playerid = pid;
    }

    public void run() {
        try {
            out.writeInt(playerid);
        } catch (IOException e1) {
            System.out.println("Failed to send PlayerID");
        }
        while (true) {
            try {
                playeridln = in.readInt();
                xin = in.readInt();
                yin = in.readInt();

                for (int i = 0; i < 10; i++) {
                    if (user[i] != null) {
                        user[i].out.writeInt(playeridln);
                        user[i].out.writeInt(xin);
                        user[i].out.writeInt(yin);
                    }
                }
            } catch (IOException e) {
                user[playerid] = null;
                break;
            }
        }

    }
}

客户

import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Client extends JPanel implements Runnable, KeyListener {

    private static final long serialVersionUID = 1L;
    static Socket socket;
    static DataInputStream in;
    static DataOutputStream out;

    int playerid;

    int[] x = new int[10];
    int[] y = new int[10];

    boolean left, up, right, down;

    int playerx;
    int playery;

    public Client() {
        init();
    }

    public void init() {
        try {
            System.out.println("Conecting to serever...");
            socket = new Socket("localhost", 7778);
            System.out.println("Connection successful");
            in = new DataInputStream(socket.getInputStream());
            playerid = in.readInt();
            out = new DataOutputStream(socket.getOutputStream());
            Input input = new Input(in, this);
            Thread thread = new Thread(input);
            thread.start();
            Thread thread2 = new Thread(this);
            thread2.start();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void updateCoordinates(int pid, int x2, int y2) {
        this.x[pid] = x2;
        this.y[pid] = y2;
    }

    public void paint(Graphics g) {
        repaint();
        for (int i = 0; i < 10; i++) {
            g.drawOval(x[i], y[i], 5, 5);
        }
    }

    public void run() {
        while (true) {
            if (right) {
                playerx += 10;
            }
            if (left) {
                playerx -= 10;
            }
            if (down) {
                playery += 10;
            }
            if (up) {
                playery -= 10;
            }
            if (right || left || up || down) {
                try {
                    out.writeInt(playerid);
                    out.writeInt(playerx);
                    out.writeInt(playery);
                } catch (Exception e) {
                    System.out.println("Erro Coordinates");
                }
            }
            repaint();
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == 37) {
            left = true;
        }
        if (e.getKeyCode() == 38) {
            up = true;
        }
        if (e.getKeyCode() == 39) {
            right = true;
        }
        if (e.getKeyCode() == 40) {
            down = true;
        }
    }

    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == 37) {
            left = false;
        }
        if (e.getKeyCode() == 38) {
            up = false;
        }
        if (e.getKeyCode() == 39) {
            right = false;
        }
        if (e.getKeyCode() == 40) {
            down = false;
        }
    }

    public void keyTyped(KeyEvent e) {
    }

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setSize(300, 300);
        f.getContentPane().add(new Client());
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

class Input implements Runnable {

    DataInputStream in;
    Client client;

    public Input(DataInputStream in, Client c) {
        this.in = in;
        this.client = c;
    }

    public void run() {
        while (true) {
            try {
                int playerd = in.readInt();
                int x = in.readInt();
                int y = in.readInt();
                client.updateCoordinates(playerd, x, y);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

当我运行代码(运行多个窗口进行检查)时,即使圆应该移动了,它也不起作用..

请帮助解决它)

先感谢您!

这是相当复杂的东西。 我可以看到两个问题。

较小的问题(我认为):Swing类和方法必须在事件队列上运行,只有很少的例外(例如Component / JComponent中的repaint()方法)。 在您的Client中,在启动线程上运行的main()方法创建一个JFrame并调用多个方法。 每个人都这样做,我认为每个人都可以摆脱它,但这很危险。 使用EventQueue.InvokeLater将代码放到UI线程上。 我检查了您的run()方法,但它们似乎没有碰到Swing(除了对repaint()的合法调用以外),但请注意它们。 从那里调用Swing方法,您会遇到更大的问题。

主要问题:在客户端运行方法某些按钮代码(在UI线程上运行)中引用了一堆字段。 playerxplayeryleftrightupdown )同步在这里并不是真正的问题。 但是,JVM没有义务(尽管可以,但可以)将其他线程所做的更改通知线程。 自己完成此操作后,我发现有时线程会立即看到更改,有时会出现明显的滞后(导致令人讨厌的跳跃图形),有时甚至永远不会看到更改。

语言规范要求在一个线程启动时,在完成连接时,在另一个线程离开同一对象上同步的块之后再进入另一个块之后,当一个易失字段被读写时,在一个线程进入同步块时在线程之间传输数据。 ,并调用Atomic方法。

因此,您要做的是手动遍历Client类中的所有字段,并确保将每个字段标记为finalvolatile 仅在synchronized块中引用仅在一个线程上引用(如Swing方法) 。 您要做的最快的事情就是使这些字段易变。 同步块可能更有效。 我相信,进入和退出它们的成本比对volatile的读取和写入要高,但是一旦您进入,就可以以很少的额外成本修改一堆字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM