如何同时运行这两个循环? (JAVA)

时间:2014-02-11 14:24:36

标签: java udp simultaneous

我试图编写一个简单的控制台程序,允许我发送和接收字符串消息。我遇到的问题是,我不知道如何同时运行接收代码和发送代码。

单独地,这些课程正在发挥作用。我可以接收数据包并发送数据包,但是让它们立刻运行对我来说似乎是不可能的。

我已经研究过多线程,但由于我的知识仍然非常基础,我似乎无法理解它是如何工作的。

这是我目前正在使用的代码。我自己编写了Dialog类,并在互联网上找到了另外两个类。

对话类:

import java.util.Scanner;


public class Dialog {

Scanner scanner = new Scanner(System.in);
User user = new User();
Network net = new Network();

ThreadReceive tr = new ThreadReceive();
ThreadSend ts = new ThreadSend();


public void run() {

    System.out.println("WELCOME");

    System.out.print("Port: ");
    while(!user.setPort(giveInput())) {
        System.out.println("Enter a valid port.");
    }

    System.out.print("IP: ");
    user.setIP(giveInput());

    System.out.println();
    System.out.println("--- CONVERSATION STARTED ---");

    tr.receive(user.getIP(), user.getPort()); // Starts receiving loop (within ThreadReceive class).

    while (true) { // Starts sending loop.
        ts.sendMessage(giveInput(), user.getIP(), user.getPort()); // Sends packet when input is given.
    }

}


private String giveInput() {

    String input = scanner.nextLine();
    return input;

}

}

接收课程:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class ThreadReceive extends Thread {

public void receive(String ip, int port) {

    try {

        // Create a socket to listen on the port.
        DatagramSocket dsocket = new DatagramSocket(port);

        // Create a buffer to read datagrams into. If a
        // packet is larger than this buffer, the
        // excess will simply be discarded!
        byte[] buffer = new byte[2048];

        // Create a packet to receive data into the buffer
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        // Now loop forever, waiting to receive packets and printing them.
        while (true) {
            // Wait to receive a datagram
            dsocket.receive(packet);

            // Convert the contents to a string, and display them
            String msg = new String(buffer, 0, packet.getLength());
            System.out.println(packet.getAddress().getHostName() + ": " + msg);

            // Reset the length of the packet before reusing it.
            packet.setLength(buffer.length);
        }

    }

    catch (Exception e) {
        System.err.println(e);
    }

}

}

发送课程:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;


public class ThreadSend extends Thread {

public void sendMessage(String message, String ip, int port) {

        try {
            byte[] data = message.getBytes();

            InetAddress address = InetAddress.getByName(ip);

            DatagramPacket packet = new DatagramPacket(data, data.length, address, port);

            DatagramSocket datagramSocket = new DatagramSocket();
            datagramSocket.send(packet);
        } 

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

}

此外,有没有办法测试我是否可以接收数据包?我和朋友一直在测试它,但自己做这件事会更方便。

谢谢!

2 个答案:

答案 0 :(得分:0)

查看Beej的网络编程指南:http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html - 这将为您提供更多示例以供查看。就测试而言,您可以设置虚拟机或使用您拥有的其他计算机。当我不得不在学校学习网络时,我们会将两个独立的Linux盒子用于测试我们的代码。

编辑:另外为了确保您正确接收,您可以使发送方和接收方都打印出他们收到的数据包数据。或者你可以让他们打印一个简单的字符串来说明收到了数据包。

如果您想要连续的流,您也可能想要检查TCP而不是UDP。 UDP只是创建一个数据报包并在网络上发送出去,而TCP在两个主机之间创建一个持久的连接。

答案 1 :(得分:0)

您没有正确使用线程。

逻辑应该在run方法中。

我建议您使用queue(如ArrayBlockingQueue)将参数传递给您的线程。例如,您可以使用一种方法将元素添加到此队列

public void addMessage(String message) {
     synchronized(inputQueue) {
          inputQueue.offer(r);
          inputQueue.notify();
     }
}

run方法将使用这些元素:

public void run() {
        try {
            while(!running) 
                    synchronized (inputQueue) {
                        inputQueue.wait();  // you can have a timeout also...
                            String message = this.inputQueue.poll();
                              // use the message item....
                              // in your case send it to the other user.
                        }
                    }       
                }
        } catch (Exception e) {
            /////// your exception handler
        }
}

记住以启动主题:

Thread t = new MyThread();
t.start(); /// Start the thread !!!

PS:消息可以是任何对象,这里使用字符串,因为我基于我的一些代码,我正在使用

Queue<String>