简体   繁体   中英

Does not work client - server

There is a problem, the following code does not work code:

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

    }
}

Client

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

When I run the code (run multiple windows to check) It does not work, even though the circle should move ..

Help to solve it, please)

Thank you in advance!

This is rather complicated stuff. There's two problems I can see.

Minor problem (I think): Swing classes and methods, with very few exceptions (such as the repaint() method in Component/JComponent) must run on the event queue. In your Client the main() method, which runs on the startup thread, creates a JFrame and calls several methods. Everybody does this, and I think everybody gets away with it, but it's dangerous. Use EventQueue.InvokeLater to put the code onto the UI thread. I checked your run() methods, but they don't seem to touch Swing, (other than a legit call to repaint()) but keep an eye on them. Call a Swing method from there and you'll have a bigger problem.

Major problem: You have a bunch of fields referenced in the Client run method and in some button code (running on the UI thread). ( playerx , playery , left , right , up , down ) Synchronization is not really a problem here. However, the JVM is under no obligation (though it can if it wants) to inform a thread of changes made by other threads. Having done this myself, I've found that sometimes the threads see changes immediately, sometimes after a noticable lag (leading to annoying, jumpy graphics), and sometimes never.

The language spec requires that data be transferred between threads when a thread starts, when it finishes with a join, when a thread enters a synch block after another thread has left a block synched on the same object, when a volatile field is written and read, and after calls to Atomic methods.

So what you want to do is go through, manually, all the fields in your Client class and for each one make sure it is marked as final , volatile , or referenced only in synchronized blocks or only referenced on one thread (like Swing methods). The quickest thing for you to do would be make those fields volatile. Synch blocks might be more efficient. I believe that they cost more to get into and out of than reads and writes to volatiles, but once in you can modify a bunch of fields at little extra cost.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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