[英]send and recieve Socket Datagram
我正在做一个服务器和客户端套接字数据报。
客户端连接到服务器,您需要在客户端中写入一个包含 Hello 或 hello 的字符串。
当服务器检测到带有 hello 或 Hello 的字符串时,用另一个字符串回复客户端。
问题是客户端没有读取服务器发送的字符串。
这是我的代码。
Client
public class Client {
public static void main(String[] args) {
try {
System.out.println("Creando socket datagram");
DatagramSocket datagramSocket = new DatagramSocket();
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Say Hello");
String saludo = myObj.nextLine();
System.out.println("Sending message");
InetAddress addr = InetAddress.getByName("localhost");
DatagramPacket datagrama = new DatagramPacket(saludo.getBytes(), saludo.getBytes().length, addr, 5555);
datagramSocket.send(datagrama);
System.out.println("Message sent");
System.out.println("Reading message");
byte[] mensaje = new byte[25];
DatagramPacket datagrama1 = new DatagramPacket(mensaje, 25);
datagramSocket.receive(datagrama1);
System.out.println("Message recieved: " + new String(mensaje));
System.out.println("Closing");
datagramSocket.close();
System.out.println("FInished");
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器
public class Server {
public static void main(String[] args) throws InterruptedException {
try {
for (;;) {
System.out.println("Creating socket datagram");
InetSocketAddress addr = new InetSocketAddress("localhost", 5555);
DatagramSocket datagramSocket = new DatagramSocket(addr);
System.out.println("RReading message");
byte[] mensaje = new byte[25];
DatagramPacket datagrama1 = new DatagramPacket(mensaje, 25);
datagramSocket.receive(datagrama1);
System.out.println("Message recieved: " + new String(mensaje));
if (new String(mensaje).contains("hello") || new String(mensaje).contains("Hello")) {
String quetal = "¿Hello, how are you doing?";
System.out.println("Sending message");
TimeUnit.SECONDS.sleep(2);
DatagramPacket datagrama2 = new DatagramPacket(quetal.getBytes(), quetal.getBytes().length, addr.getAddress(),
5555);
datagramSocket.send(datagrama2);
System.out.println("Message Sent");
}
datagramSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
我尝试在服务器中设置睡眠,以防服务器在客户端尝试读取之前发送字符串。
非常感谢您一如既往的帮助。
客户端使用无参数DatagramSocket()
构造函数绑定到一个随机端口,用于发送和接收:
构造一个数据报套接字并将其绑定到本地主机上的任何可用端口。 套接字将绑定到通配符地址,即 kernel 选择的 IP 地址。
但是,当服务器接收到数据报时,您将忽略 IP 和实际发送数据报的端口:
DatagramSocket.receive(DatagramPacket)
从这个套接字接收一个数据报包。 当此方法返回时,
DatagramPacket
的缓冲区被接收到的数据填充。 数据报包还包含发送者的 IP 地址,以及发送者机器上的端口号。
当服务器发送回复时,您将其发送回localhost:5555
的服务器本身,而不是发送给客户端。
在服务器端,您需要更改:
DatagramPacket datagrama2 = new DatagramPacket(..., addr.getAddress(), 5555);
对此:
DatagramPacket datagrama2 = new DatagramPacket(..., datagrama1.getAddress(), datagrama1.getPort());
或对此:
DatagramPacket datagrama2 = new DatagramPacket(..., datagrama1.getSocketAddress());
附带说明一下,您的服务器也忽略了客户端发送的数据的实际长度。 服务器使用 25 字节数组接收数据,但客户端实际上可能并未发送 25 字节。 如果客户端发送的字节数少于 25,您最终会得到一个包含随机垃圾的String
。 如果客户端发送超过 25 个字节,`receive() 将截断数据。
尝试更多类似的东西:
System.out.println("Reading message");
byte[] buffer = new byte[65535];
DatagramPacket datagrama1 = new DatagramPacket(buffer, buffer.length);
datagramSocket.receive(datagrama1);
String mensaje = new String(datagrama1.getData(), datagrama1.getLength());
System.out.println("Message recieved: " + mensaje);
if (mensaje.contains("hello") || mensaje.contains("Hello")) {
...
}
这很有趣:)
请记住,这种编码方式可能不是最好的,但它可以按您的意愿工作。
客户端发送Hello,服务器接收Hello,然后发送(Hello back at you)。
然后两者都终止。 它不会永远循环这两条消息,但我向你展示了这个想法。
服务器也需要充当客户端才能发送消息。
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class DReceiver{
public static void replyToTheClientListening() throws IOException {
DatagramSocket ds = new DatagramSocket();
String str = "hello back at you";
InetAddress ia = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), ia, 3001);
ds.send(dp);
ds.close();
}
public static void listenToMessagesFromTheClient() throws IOException {
DatagramSocket ds = new DatagramSocket(3000);
ds.setSoTimeout(60000); //Wait 60 SECONDS for messages
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 1024);
ds.receive(dp);
String strRecv = new String(dp.getData(), 0, dp.getLength());
if("hello".equalsIgnoreCase(strRecv)) { //hello in any case
System.out.println("Received a MSG from the Client " + strRecv);
replyToTheClientListening();
}
ds.close();
}
public static void main(String[] args) throws Exception {
listenToMessagesFromTheClient();
}
}
DSender 是客户端,但也需要充当服务器(监听来自其他服务器的消息)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
public class DSender{
public static void actAsAServerAndListenToMessages() throws IOException {
//Listen to Port 3001 --The Server will send to that port
DatagramSocket dsReceive = new DatagramSocket(3001);
dsReceive.setSoTimeout(60000); //Make it wait 60 SECONDS
byte[] buf = new byte[1024];
DatagramPacket dpReceive = new DatagramPacket(buf, 1024);
dsReceive.receive(dpReceive);
String strRecv = new String(dpReceive.getData(), 0, dpReceive.getLength());
System.out.println("Client -- Received a Msg back from Server --" + strRecv);
dsReceive.close();
}
public static void sendAMessageAsAClientToTheServer() throws IOException {
// Client will send a message to Port 3000 which the Server listens to.
DatagramSocket ds = new DatagramSocket();
String str = "hello";
InetAddress ia = InetAddress.getByName("127.0.0.1");
DatagramPacket dp = new DatagramPacket(str.getBytes(), str.length(), ia, 3000);
ds.send(dp);
ds.close();
}
public static void main(String[] args) throws Exception {
sendAMessageAsAClientToTheServer();
actAsAServerAndListenToMessages();
}
}
参考: https://www.javatpoint.com/DatagramSocket-and-DatagramPacket
我运行服务器,然后是客户端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.