我写了两个程序。现在每个程序都使用线程来同时发送和接收数据包。 每当我从服务器向客户端发送数据包时,客户端的消息就会在无限循环中被接收。 IE;我添加了一个打印语句来打印发送的消息,并且这会永远处于无限循环中。我想让它接收消息,然后能够写回服务器并在用户需要时退出。
我尝试过使用socket.close(),但这使得客户端收到消息而我只能写回服务器一次。发送完之后,就无法再发送了。我想这样做,以便我可以多次回信。
谁能给我指出正确的方向吗?
我的代码如下;
public class UDPThreadClient extends Thread {
public static int port1;
//Create threaded server
UDPThreadClient (int port1) {
System.out.println ("Starting threaded client");
start();
}
public void run() {
int port = port1;
try {
DatagramSocket serverSocket = new DatagramSocket(port1);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
SocketAddress address = receivePacket.getSocketAddress();
System.out.println("RECEIVED from " + address + " : " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
//int port = receivePacket.getPort();
String capitalizedSentence = sentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
//serverSocket.close();
}
} catch (IOException e) {
System.out.println (e.getMessage());
}
}
//Create client
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
port1 = Integer.parseInt(args[1]);
new UDPThreadClient (port1);
try {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
//clientSocket.close();
} catch (IOException e) {
System.out.println (e.getMessage());
}
}
}
和
public class UDPThreadServer extends Thread {
public static int port1;
//Create threaded client
UDPThreadServer () {
System.out.println ("Starting threaded server");
start();
}
public void run() {
try {
DatagramSocket clientSocket = new DatagramSocket();
BufferedReader inFromUser = new BufferedReader (new InputStreamReader(System.in));
Scanner in = new Scanner (inFromUser);
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte [1024];
byte[] receiveData = new byte [1024];
while (in.hasNextLine()) {
String sentence = in.nextLine();
//inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket (sendData, sendData.length, IPAddress, port1);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket (receiveData, receiveData.length);
clientSocket.receive (receivePacket);
String modSentence = new String (receivePacket.getData());
System.out.println ("FROM SERVER: " + modSentence);
}
//clientSocket.close();
} catch (IOException e) {
System.out.println (e.getMessage());
}
}
//Create server
public static void main(String[] args) {
int port = Integer.parseInt(args[0]);
port1 = Integer.parseInt(args[1]);
new UDPThreadServer ();
try {
DatagramSocket serverSocket = new DatagramSocket (port);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true) {
DatagramPacket receivePacket = new DatagramPacket (receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
SocketAddress address = receivePacket.getSocketAddress();
System.out.println ("Received from " + address + " : " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
String capSentence = sentence.toUpperCase();
sendData = capSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket (sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
//serverSocket.close();
}
} catch (IOException e) {
System.out.println (e.getMessage());
}
}
}
谢谢。
最佳答案
查看 UDPClientServer:
当您创建数据报包时,您为其指定发送数据的端口,而不是发送数据的端口。
当我运行你的代码时,什么也没有发生。服务器正在端口 port
上等待,而客户端则向端口 port1
发送数据。如果您改为发送到端口port
(无法从主方法访问,但将其更改为字段而不是本地方法可以解决此问题,则会发生无限循环,因为服务器将数据包发送到它正在监听的同一端口。这就是您的问题。您是否提供与程序的第一个和第二个参数相同的数字?
在服务器上,您可以使用 receivePacket.getPort()
获取数据包来自的端口。
编辑:
您的两个类(class)有很多重复,这可能是造成困惑的根源。一个类有一个 main,它启动一个客户端,然后创建一个服务器类型循环测试器。另一个类设置一个服务器,然后创建一个客户端类型测试器。
下面只是您命名为 UDPThreadServer 的类,其中的注释显示了使服务器“与 main 方法中的测试代码一起工作”的更改。请注意,服务器应发送到它未监听的端口。您还可以从命令行参数读取端口值。我只是为端口编写了一些数字并将它们作为常量插入。
public class UDPThreadServer extends Thread
{
public static int port1;
UDPThreadServer()
{
//server or client? it's hard to say. you call the socket a clientSocket.
System.out.println("Starting threaded server");
start();
}
public void run()
{
try
{
// Here client(?) is set up with empty constructor.
// It is a mystery what port it will get.
DatagramSocket clientSocket = new DatagramSocket();
BufferedReader inFromUser =
new BufferedReader(new InputStreamReader(System.in));
Scanner in = new Scanner(inFromUser);
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
while (in.hasNextLine())
{
String sentence = in.nextLine();
// inFromUser.readLine();
sendData = sentence.getBytes();
// sending to port1? that must be the server.
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port1);
clientSocket.send(sendPacket);
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER: " + modSentence);
}
// clientSocket.close();
} catch (IOException e)
{
System.out.println(e.getMessage());
}
}
// Create server
public static void main(String[] args)
{
// int port = Integer.parseInt(args[0]);
int port = 1927; // or whatever
// port1 = Integer.parseInt(args[1]);
port1 = 1928;
new UDPThreadServer();
try
{
// server resides on port1? if client sends to port 1, then this is so.
DatagramSocket serverSocket = new DatagramSocket(port1);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true)
{
DatagramPacket receivePacket =
new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
SocketAddress address = receivePacket.getSocketAddress();
System.out.println("Received from " + address + " : " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
String capSentence = sentence.toUpperCase();
sendData = capSentence.getBytes();
// where did you get the info from? Client is set up with an empty constructor, so it is a mystery.
port = receivePacket.getPort();
DatagramPacket sendPacket =
new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
// serverSocket.close();
}
} catch (IOException e)
{
System.out.println(e.getMessage());
}
}
}
关于java - Java中的UDP线程无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6185767/