所以在过去的几天里,我一直在开发一个udp api,我尝试先在本地机器上测试我的api。
所以我在不同的线程中创建了一个服务器和一个客户端示例。
当我用客户机向服务器发送数据包时,服务器收到了这些数据包,但当我试图从服务器向客户机发送数据包时,服务器只是将其消息发送给自己,并对其接收到的数据包做出响应,最终形成了无限消息发送的循环。
以下是当前代码的一些部分:
客户
服务器
客户:
package com.github.sebyplays.jsimpleudp;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
import java.util.concurrent.TimeUnit;
public class Client implements ICommunicator{
@Getter private DatagramSocket datagramSocket;
private boolean running;
@Getter @Setter private byte[] buffer = new byte[1024];
@Getter @Setter private PacketReceiver packetReceiver;
@Getter @Setter private InetAddress host;
private Type type = Type.CLIENT;
@Getter private int port;
@Getter private DatagramPacket lastReceivedPacket;
@Getter private DatagramPacket lastSentPacket;
private long lastReceivedTime = 0;
private long lastSentTime = 0;
@SneakyThrows
public Client(String host, int port, PacketReceiver packetReceiver) {
this.packetReceiver = packetReceiver;
this.port = port;
this.host = InetAddress.getByName(host);
this.datagramSocket = new DatagramSocket();
}
@Override
public void start() {
running = true;
Thread thread = new Thread("udpclient"){
@SneakyThrows
@Override
public void run() {
while (running){
DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length, host, port);
datagramSocket.receive(datagramPacket);
lastReceivedPacket = datagramPacket;
lastReceivedTime = System.currentTimeMillis();
callReceiver(datagramPacket);
}
}
};
thread.start();
}
@Override
public void stop() {
running = false;
if(!datagramSocket.isClosed()){
datagramSocket.close();
}
}
public void sendPacket(DatagramPacket datagramPacket){
try {
datagramSocket.send(datagramPacket);
lastSentPacket = datagramPacket;
lastSentTime = System.currentTimeMillis();
} catch (IOException e) {
e.printStackTrace();
}
}
public void callReceiver(DatagramPacket datagramPacket){
packetReceiver.onPacket(this, datagramPacket, datagramPacket.getAddress(),
new String(datagramPacket.getData(), 0, datagramPacket.getLength()), this.getType());
}
@Override
public Type getType() {
return this.type;
}
@Override
public void sendMessage(InetAddress inetAddress, String message){
byte[] messageBytes = message.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(messageBytes, messageBytes.length, inetAddress, port);
sendPacket(datagramPacket);
}
@Override
public long getLastReceivedTime() {
return System.currentTimeMillis() - lastReceivedTime;
}
@Override
public long getLastSentTime() {
return System.currentTimeMillis() - lastSentTime;
}
public static void main(String[] args) {
Client client = new Client("mcsilent.de", 2312, new PacketReceiver() {
@Override
public void onPacket(ICommunicator iCommunicator, DatagramPacket datagramPacket, InetAddress source, String packet, Type type) {
System.out.println(packet);
}
});
client.start();
Scanner scanner = new Scanner(System.in);
while (true){
if(scanner.nextLine().equalsIgnoreCase("r")){
client.sendMessage(client.getHost(), "InfoRequest::lobby01");
}
}
}
}
服务器:
package com.github.sebyplays.jsimpleudp;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class Server implements ICommunicator{
@Getter private DatagramSocket datagramSocket;
private boolean running;
@Getter @Setter private byte[] buffer = new byte[1024];
private Type type = Type.SERVER;
private int port;
@Getter @Setter private PacketReceiver packetReceiver;
@Getter private DatagramPacket lastReceivedPacket;
@Getter private DatagramPacket lastSentPacket;
private long lastReceivedTime = 0;
private long lastSentTime = 0;
public Server(int port, PacketReceiver packetReceiver) throws SocketException {
this.datagramSocket = new DatagramSocket(port);
this.packetReceiver = packetReceiver;
this.port = port;
}
public void start(){
this.running = true;
Thread thread = new Thread("udpserver"){
@SneakyThrows
@Override
public void run() {
while (running){
DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length);
datagramSocket.receive(datagramPacket);
lastReceivedPacket = datagramPacket;
lastReceivedTime = System.currentTimeMillis();
callReceiver(datagramPacket);
}
}
};
thread.start();
}
@Override
public void stop(){
this.running = false;
if(!datagramSocket.isClosed()){
datagramSocket.close();
}
}
public void sendPacket(DatagramPacket datagramPacket){
try {
datagramSocket.send(datagramPacket);
lastSentPacket = datagramPacket;
lastSentTime = System.currentTimeMillis();
} catch (IOException e) {
e.printStackTrace();
}
}
public void callReceiver(DatagramPacket datagramPacket){
packetReceiver.onPacket(this, datagramPacket, datagramPacket.getAddress(),
new String(datagramPacket.getData(), 0, datagramPacket.getLength()), this.getType());
}
@Override
public Type getType() {
return this.type;
}
@Override
public void sendMessage(InetAddress inetAddress, String message) {
byte[] messageBytes = message.getBytes();
DatagramPacket datagramPacket = new DatagramPacket(messageBytes, messageBytes.length, inetAddress, port);
sendPacket(datagramPacket);
}
@Override
public long getLastReceivedTime() {
return System.currentTimeMillis() - lastReceivedTime;
}
@Override
public long getLastSentTime() {
return System.currentTimeMillis() - lastSentTime;
}
}
2条答案
按热度按时间hsvhsicv1#
在此服务器例程中:
我能在范围中看到的唯一“端口”是示例成员变量
服务器正在侦听的端口。所以,您将这个数据报发送给自己(假设客户端和服务器的ip地址相同)。
您应该从接收到的数据报中提取源地址和端口。
fzsnzjdm2#
我已经解决了我的问题,并将公布答案供公众参考。
两个端点都在同一主机上、同一端口上侦听。
他们无法区分彼此,因此引起了很大的混乱。客户端与服务器在同一端口上侦听数据包。此外,客户端在与服务器相同的端口上发送数据包,客户端在该端口上侦听数据包。
因此,问题的解决方法只是为每个示例选择不同的侦听端口。
例如,客户端正在侦听端口31254,服务器正在侦听2132。客户端将数据包发送到2132,服务器发送到31254。
正如伊吉猜测的那样。
非常感谢你们。