英文:
Client sends the numbers to the server, but the server doesn't send them back
问题
以下是翻译好的内容:
客户端代码:
import javax.xml.crypto.Data;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
InetSocketAddress ep = new InetSocketAddress("127.0.0.1", 1234);
String broj1, broj2;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the 1st number: ");
broj1 = sc.nextLine();
System.out.println();
System.out.print("Enter the 2nd number: ");
broj2 = sc.nextLine();
if (broj1.contains("[a-zA-Z+]") == true && broj2.contains("[a-zA-Z+]")) {
System.out.println("You did not enter numbers.");
System.exit(0);
}
byte[] brojJedan = new byte[256];
byte[] brojDva = new byte[256];
brojJedan = broj1.getBytes();
brojDva = broj2.getBytes();
DatagramPacket packet1 = new DatagramPacket(brojJedan, brojJedan.length, ep);
DatagramPacket packet2 = new DatagramPacket(brojDva, brojDva.length, ep);
try (DatagramSocket Klijent = new DatagramSocket(1000)) {
Klijent.send(packet1);
Klijent.send(packet2);
byte[] rezultat = new byte[256];
DatagramPacket packetRezultat = new DatagramPacket(rezultat, rezultat.length, ep);
Klijent.receive(packetRezultat);
System.out.println(new String(packetRezultat.getData(), 0, packetRezultat.getLength()));
} catch (Exception ex) {
}
}
}
服务器端代码:
import javax.xml.crypto.Data;
import java.awt.*;
import java.net.*;
import java.nio.ByteBuffer;
public class Main {
public static void main(String[] args) {
try {
DatagramSocket serverSocket = new DatagramSocket(1234);
byte[] buff1 = new byte[256];
byte[] buff2 = new byte[256];
byte[] buffRezultat = new byte[256];
while (true) {
System.out.println("Client connected.");
DatagramPacket p1 = new DatagramPacket(buff1, buff1.length);
DatagramPacket p2 = new DatagramPacket(buff2, buff2.length);
serverSocket.receive(p1);
System.out.println("p1 received");
serverSocket.receive(p2);
System.out.println("p2 received");
int rezultat, brojJedan, brojDva;
brojJedan = ByteBuffer.wrap(p1.getData()).getInt();
brojDva = ByteBuffer.wrap(p2.getData()).getInt();
System.out.println("byte converted to int");
rezultat = brojJedan + brojDva;
System.out.println("numbers added");
buffRezultat = ByteBuffer.allocate(4).putInt(rezultat).array();
DatagramPacket pRez = new DatagramPacket(buffRezultat, buffRezultat.length);
serverSocket.send(pRez);
System.out.println("result sent");
}
} catch (Exception ex) {
}
}
}
英文:
I've searched for answers, but can't quite fix the code.
I want the client to send numbers to the server, the server adds up 2 numbers and sends them back. The thing is, client sends them to the server, server adds them up (at least I think it does) but it doesn't send anything back. I'm posting Client code now:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
InetSocketAddress ep = new InetSocketAddress("127.0.0.1", 1234);
String broj1, broj2;
Scanner sc = new Scanner(System.in);
System.out.print("Unesite 1. broj: ");
broj1 = sc.nextLine();
System.out.println();
System.out.print("Unesite 2. broj: ");
broj2 = sc.nextLine();
if(broj1.contains("[a-zA-Z+]")==true&&broj2.contains("[a-zA-Z+]")){
System.out.println("Niste unijeli brojeve.");
System.exit(0);
}
byte[] brojJedan = new byte[256];
byte[] brojDva = new byte[256];
brojJedan = broj1.getBytes();
brojDva = broj2.getBytes();
DatagramPacket packet1 = new DatagramPacket(brojJedan, brojJedan.length, ep);
DatagramPacket packet2 = new DatagramPacket(brojDva, brojDva.length, ep);
try(DatagramSocket Klijent = new DatagramSocket(1000)){
Klijent.send(packet1);
Klijent.send(packet2);
byte[] rezultat = new byte[256];
DatagramPacket packetRezultat = new DatagramPacket(rezultat, rezultat.length, ep);
Klijent.receive(packetRezultat);
System.out.println(new String(packetRezultat.getData(), 0, packetRezultat.getLength()));
}catch(Exception ex){}
}
}
Server code:
import java.awt.*;
import java.net.*;
import java.nio.ByteBuffer;
public class Main{
public static void main(String[] args) {
try {
DatagramSocket serverSocket = new DatagramSocket(1234);
byte[] buff1 = new byte[256];
byte[] buff2 = new byte[256];
byte[] buffRezultat = new byte[256];
while(true){
System.out.println("Client connected.");
DatagramPacket p1 = new DatagramPacket(buff1,buff1.length);
DatagramPacket p2 = new DatagramPacket(buff2, buff2.length);
serverSocket.receive(p1);
System.out.println("p1 recieved");
serverSocket.receive(p2);
System.out.println("p2 recieved");
int rezultat, brojJedan, brojDva;
brojJedan = ByteBuffer.wrap(p1.getData()).getInt();
brojDva = ByteBuffer.wrap(p2.getData()).getInt();
System.out.println("byte converted to int");
rezultat = brojJedan+brojDva;
System.out.println("numbers added");
buffRezultat = ByteBuffer.allocate(1).putInt(rezultat).array();
DatagramPacket pRez = new DatagramPacket(buffRezultat, buffRezultat.length);
serverSocket.send(pRez);
System.out.println("res sent");
}
}catch(Exception ex){}
}
}```
</details>
# 答案1
**得分**: 2
你的代码存在一些问题:
客户端部分:
1. 在客户端将一个 `String` 放入输出的 `byte[]` 中,但在服务器端期望接收一个 `int`。
2. 在使用 `DatagramSocket` 时使用了端口 1000,实际上不应该使用任何端口。
3. 在服务器端期望从输入的 `byte[]` 中接收一个 `String`,但实际上在其中放入了一个 `int`。
服务器端部分:
1. 为了从 `byte[]` 中接收一个 `int`(32 位),你需要读取四个字节(每个字节8位)。
2. 为了通过 `byte[]` 发送一个 `int`,你需要分配四个字节的空间。
3. 从服务器发送回客户端的 `DatagramPacket` 需要知道客户端的地址和端口。
这份代码是有效的:
```java
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
InetSocketAddress ep = new InetSocketAddress("127.0.0.1", 1234);
String broj1, broj2;
Scanner sc = new Scanner(System.in);
System.out.print("Unesite 1. broj: ");
broj1 = sc.nextLine();
System.out.println();
System.out.print("Unesite 2. broj: ");
broj2 = sc.nextLine();
if (broj1.contains("[a-zA-Z+]") && broj2.contains("[a-zA-Z+]")) {
System.out.println("Niste unijeli brojeve.");
System.exit(0);
}
byte[] brojJedan = ByteBuffer.allocate(4).putInt(Integer.parseInt(broj1)).array();
byte[] brojDva = ByteBuffer.allocate(4).putInt(Integer.parseInt(broj2)).array();
DatagramPacket packet1 = new DatagramPacket(brojJedan, brojJedan.length, ep);
DatagramPacket packet2 = new DatagramPacket(brojDva, brojDva.length, ep);
try (DatagramSocket Klijent = new DatagramSocket()) {
Klijent.send(packet1);
Klijent.send(packet2);
byte[] rezultat = new byte[256];
DatagramPacket packetRezultat = new DatagramPacket(rezultat, rezultat.length, ep);
Klijent.receive(packetRezultat);
System.out.println(ByteBuffer.wrap(packetRezultat.getData(), 0, 4).getInt());
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;
public class Server {
public static void main(String[] args) {
try {
DatagramSocket serverSocket = new DatagramSocket(1234);
byte[] buff1 = new byte[256];
byte[] buff2 = new byte[256];
byte[] buffRezultat = new byte[256];
while (true) {
System.out.println("Client connected.");
DatagramPacket p1 = new DatagramPacket(buff1, buff1.length);
DatagramPacket p2 = new DatagramPacket(buff2, buff2.length);
serverSocket.receive(p1);
System.out.println("p1 received");
serverSocket.receive(p2);
System.out.println("p2 received");
int rezultat, brojJedan, brojDva;
brojJedan = ByteBuffer.wrap(p1.getData(), 0, 4).getInt();
brojDva = ByteBuffer.wrap(p2.getData(), 0, 4).getInt();
System.out.println("byte converted to int " + brojDva + " " + brojJedan);
rezultat = brojJedan + brojDva;
System.out.println("numbers added " + rezultat);
buffRezultat = ByteBuffer.allocate(4).putInt(rezultat).array();
DatagramPacket pRez = new DatagramPacket(buffRezultat, buffRezultat.length, p2.getAddress(), p2.getPort());
serverSocket.send(pRez);
System.out.println("res sent");
}
} catch (Exception ex) {
}
}
}
尽管这份代码在某些输入情况下可能会工作,但仍然存在一些弱点:
-
输入验证只检查是否使用了字母,这并不一定能确保你得到一个数字(查看这个 Stack Overflow 帖子)。
-
为了传输两个
int
,你不需要发送两个DatagramPacket
,一个足够了。 -
使用标准的输入/输出流将有助于你在字节数组上进行写入和读取。
-
实现有意义的异常消息将有助于你编写代码并让用户使用软件。
英文:
Your code contains a number of problems:
On the client side:
-
You are putting a
String
into the outboundbyte[]
while expecting anint
on the server side. -
You are using port 1000 with the
DatagramSocket
while you shouldn't use any. -
You are expecting a
String
from the inboundbyte[]
while putting anint
into it on the server side.
On the server side:
-
In order to receive one
int
(32 bits) from abyte[]
you have to read four bytes (8 bits each). -
In order to send one
ìnt
via abyte[]
you have to allocate four bytes. -
The
DatagramPacket
you send back from the server to the client needs to know the client's address and port.
This code works:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
InetSocketAddress ep = new InetSocketAddress("127.0.0.1", 1234);
String broj1, broj2;
Scanner sc = new Scanner(System.in);
System.out.print("Unesite 1. broj: ");
broj1 = sc.nextLine();
System.out.println();
System.out.print("Unesite 2. broj: ");
broj2 = sc.nextLine();
if(broj1.contains("[a-zA-Z+]")&&broj2.contains("[a-zA-Z+]")){
System.out.println("Niste unijeli brojeve.");
System.exit(0);
}
byte[] brojJedan = ByteBuffer.allocate(4).putInt(Integer.parseInt(broj1)).array();
byte[] brojDva = ByteBuffer.allocate(4).putInt(Integer.parseInt(broj2)).array();
DatagramPacket packet1 = new DatagramPacket(brojJedan, brojJedan.length, ep);
DatagramPacket packet2 = new DatagramPacket(brojDva, brojDva.length, ep);
try(DatagramSocket Klijent = new DatagramSocket()){
Klijent.send(packet1);
Klijent.send(packet2);
byte[] rezultat = new byte[256];
DatagramPacket packetRezultat = new DatagramPacket(rezultat, rezultat.length, ep);
Klijent.receive(packetRezultat);
System.out.println(ByteBuffer.wrap(packetRezultat.getData(), 0, 4).getInt());
}catch(Exception e){
e.printStackTrace();
}
}
}
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;
public class Server {
public static void main(String[] args) {
try {
DatagramSocket serverSocket = new DatagramSocket(1234);
byte[] buff1 = new byte[256];
byte[] buff2 = new byte[256];
byte[] buffRezultat = new byte[256];
while (true) {
System.out.println("Client connected.");
DatagramPacket p1 = new DatagramPacket(buff1, buff1.length);
DatagramPacket p2 = new DatagramPacket(buff2, buff2.length);
serverSocket.receive(p1);
System.out.println("p1 recieved");
serverSocket.receive(p2);
System.out.println("p2 recieved");
int rezultat, brojJedan, brojDva;
brojJedan = ByteBuffer.wrap(p1.getData(), 0, 4).getInt();
brojDva = ByteBuffer.wrap(p2.getData(), 0, 4).getInt();
System.out.println("byte converted to int" + brojDva + " " + brojJedan);
rezultat = brojJedan + brojDva;
System.out.println("numbers added " + rezultat);
buffRezultat = ByteBuffer.allocate(4).putInt(rezultat).array();
DatagramPacket pRez = new DatagramPacket(buffRezultat, buffRezultat.length, p2.getAddress(), p2.getPort());
serverSocket.send(pRez);
System.out.println("res sent");
}
} catch (Exception ex) {
}
}
}
While this code would work (for certain input), it still does have a few weak spots:
-
The input validation only checks if letters are not used. This does not necessarily give you a number (check out this SO post).
-
You don't need to send two
DatagramPacket
s in order to transfer twoint
s; one is enough. -
Using standard I/O streams would help you writing to and reading from byte arrays.
-
Implementing meaningful exception messages would help you write the code and users use the software.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论