2015-07-12 3 views
0

Итак, я изучаю 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()); 
    } 
} 

Может быть, это потому, что это не Syncd правильно и сервер посылает сообщение до того, как клиент получает ту часть кода, где он проверяет сообщение? Я понятия не имею, потому что я действительно новичок в этом. Мне бы хотелось поставить диагноз, почему это происходит и как это исправить! Извините за беспорядочный код, я новичок в этом и кодировании в целом.

ответ

0

Скорее всего, вы столкнулись с проблемами синхронизации из-за того, что вы продолжаете открывать и закрывать серверный сокет. Это создает race condition между отправкой() и созданием сервера DatagramSocket. Если клиент отправляет свой пакет до инициализации сокета сервера, сервер его не получит и просто ждет его навсегда. Это называется deadlock.

Чтобы избежать этой проблемы, просто держите гнездо сервера открытым. Откройте его, когда объект Server будет инициализирован и закроется, когда закончится программа сервера. Таким образом, датаграммы, отправленные клиентом, будут храниться в буфере сокета до тех пор, пока сервер не назовет receive().

С другой стороны, конструктор сервера и метод run() имеют много дублирующегося кода. Дублирование кода часто приводит к несоответствиям в логике программы и, следовательно, ошибкам. Старайтесь избегать копирования кода.

Смежные вопросы