繁体   English   中英

为什么我的简单网络程序中断了?

[英]Why is my simple networking program breaking?

因此,我正在使用Internet上的指南来学习UDP网络。 我找到了一个指南,主要是复制/粘贴的代码,并且有效。 因此,显然我想自己扩展。 我正在尝试做一个简单的事情,它将为服务器提供客户端鼠标的位置,然后服务器将向所有大写字母发送完全相同的消息。 但是由于某种原因,它可以在0-100倍的时间内完美运行,然后停止。 这是我的代码:

服务器:

public class Server implements Runnable {

    boolean running = false;
    long time;
    InetAddress IPAddress;
    int port;

    public static void main(String[] args) throws Exception {
        Thread th = new Thread(new Server());
        th.start();
    }

    public Server() throws Exception {
        DatagramSocket serverSocket = new DatagramSocket(9876);
        byte[] receiveData = new byte[1024];
        byte[] sendData = new byte[1024];

        System.out.println("Server started");
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        serverSocket.receive(receivePacket);
        IPAddress = receivePacket.getAddress();
        port = receivePacket.getPort();

        System.out.println("Client connected at " + IPAddress);
        String send = "Connected!";
        sendData = send.getBytes();

        DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
        serverSocket.send(sendPacket);
        serverSocket.close();

        time = System.nanoTime();
        running = true;
    }

    public void run() {     
        int x = 0;
        while(running) {
            if(System.nanoTime() > time + 60/(1e9)) {
                time = System.nanoTime();
                try { 
                    x++;
                    DatagramSocket serverSocket = new DatagramSocket(9876);
                    byte[] receiveData = new byte[1024];
                    byte[] sendData = new byte[1024];

                    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                    serverSocket.receive(receivePacket);
                    System.out.println("Received message");

                    IPAddress = receivePacket.getAddress();
                    port = receivePacket.getPort();

                    String sentence = new String(receivePacket.getData());
                    System.out.println("RECEIVED " + sentence);

                    String capSentence = sentence.toUpperCase();
                    sendData = capSentence.getBytes();

                    DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
                    serverSocket.send(sendPacket);
                    System.out.println("Sent message.");
                    System.out.println(x);
                    serverSocket.close();   
                } catch(Exception e) {
                    System.out.println(e.getMessage());
                }
            }
        }
    }
}

客户:

public class Client implements Runnable {

    boolean foundConnection = false;
    boolean running = false;        
    long time;

    public static void main(String[] args) throws Exception {
        Thread th = new Thread(new Client());
        th.start();
    }

    public Client() throws Exception {
        time = System.nanoTime();
        running = true;
    }

    public void run() {
        while(running) {
            if(System.nanoTime() > time + (60/1e9)) {
                time = System.nanoTime();

                try {
                    DatagramSocket clientSocket = new DatagramSocket();
                    InetAddress IPAddress = InetAddress.getByName("localhost");

                    byte[] sendData = new byte[1024];
                    byte[] receiveData = new byte[1024];

                    String send = "Mouse is at " + mouse();
                    sendData = send.getBytes();

                    DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
                    clientSocket.send(sendPacket);
                    System.out.println("Sent message.");

                    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
                    clientSocket.receive(receivePacket);
                    System.out.println("Received message.");

                    String modSentence = new String(receivePacket.getData());
                    System.out.println("FROM SERVER: " + modSentence);
                    clientSocket.close();
                } catch(Exception e) {
                    System.out.println("Error"); 
                }
            }
        }
    }

    public static Point mouse() {
        return new Point((int)MouseInfo.getPointerInfo().getLocation().getX(), 
                (int)MouseInfo.getPointerInfo().getLocation().getY());
    }
}

也许是因为未正确同步并且服务器正在发送消息,然后客户端才能到达代码部分以检查消息吗? 我不知道,因为我真的很陌生。 我很想知道为什么这种情况发生以及如何解决! 对不起,代码混乱,我对此并不陌生,通常来说还是编码。

由于您不断打开和关闭服务器套接字,因此您很可能遇到同步问题。 这将在客户端的send()与服务器的DatagramSocket创建之间创建竞争条件 如果客户端在初始化服务器的套接字之前发送了它的数据包,则服务器将不会收到它,而是永远等待它。 这称为死锁

为避免此问题,只需保持服务器的套接字打开即可。 初始化Server对象时将其打开,并在服务器程序结束时将其关闭。 这样,客户端发送的数据报将保留在套接字缓冲区中,直到服务器调用receive()为止。

另外,服务器的构造函数和run()方法有很多重复的代码。 代码重复经常导致程序逻辑上的不一致,从而导致错误。 尽量避免粘贴粘贴代码。

暂无
暂无

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

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