我正在尝试制作一个包含客户端,中间主机和服务器的程序。客户端将数据包发送到主机,主机将其发送到服务器,然后服务器将数据包发送回发送给客户端的主机。这应该重复11次。 这是我的代码:
public class SimpleEchoClient {
DatagramPacket sendPacket, receivePacket;
DatagramSocket sendReceiveSocket;
public SimpleEchoClient()
{
try {
sendReceiveSocket = new DatagramSocket();
} catch (SocketException se) { // Can't create the socket.
se.printStackTrace();
System.exit(1);
}
}
public byte[] createWriteByte() {
byte[] msg = new byte[100];
int position = 2;
Path path = Paths.get("test.txt");
String fileName = path.getFileName().toString();
//In datagrampackets, our data needs to be converted into bytes
msg = new byte[100];
msg[0] = 0x00;
msg[1] = 0x02;
for(int i=0; i<fileName.getBytes().length; i++) {
msg[position] = fileName.getBytes()[i];
position++;
}
msg[position] = 0x00;
String mode = "netascii";
position++;
for(int i = 0; i < mode.getBytes().length; i++) {
msg[position] = mode.getBytes()[i];
position++;
}
msg[position] = 0;
return msg;
}
public byte[] createReadByte() {
byte[] msg = new byte[100];
int position = 2;
Path path = Paths.get("test.txt");
String fileName = path.getFileName().toString();
//In datagrampackets, our data needs to be converted into bytes
msg = new byte[100];
msg[0] = 0x00;
msg[1] = 0x01;
for(int i=0; i<fileName.getBytes().length; i++) {
msg[position] = fileName.getBytes()[i];
position++;
}
msg[position] = 0x00;
String mode = "netascii";
position++;
for(int i = 0; i < mode.getBytes().length; i++) {
msg[position] = mode.getBytes()[i];
position++;
}
msg[position] = 0;
return msg;
}
public void sendAndReceive(boolean checkRead)
{
Path path = Paths.get("test.txt");
String fileName = path.getFileName().toString();
//In datagrampackets, our data needs to be converted into bytes
byte[] msg;
if(checkRead) {
msg = createReadByte();
checkRead = false;
}else{
msg = createWriteByte();
checkRead = true;
}
String str = new String(msg);
System.out.println(str);
System.out.println("Hello");
System.out.println(msg);
try {
sendPacket = new DatagramPacket(msg, msg.length,
InetAddress.getLocalHost(), 5000);
} catch (UnknownHostException e) {
e.printStackTrace();
System.exit(1);
}
try {
sendReceiveSocket.send(sendPacket);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
sendReceiveSocket.close();
try {
Thread.sleep(5000);
} catch (InterruptedException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
System.out.println("Client: Packet sent.\n");
//NOW TO RECEIVE THE DATA
DatagramSocket receiveSocket = null;
try {
receiveSocket = new DatagramSocket(5000);
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte data[] = new byte[4];
receivePacket = new DatagramPacket(data, data.length);
try {
// Block until a datagram is received via sendReceiveSocket.
receiveSocket.receive(receivePacket);
} catch(IOException e) {
e.printStackTrace();
System.exit(1);
}
// Process the received datagram.
for(int j =0; j < data.length; j++) {
System.out.println(data[j] & 0xff);
}
// We're finished, so close the socket.
sendReceiveSocket.close();
}
public static void main(String args[])
{
boolean checkRead = true;
int count =0;
for(int i = 0; i<10; i++) {
System.out.println("Count:" + count);
SimpleEchoClient c = new SimpleEchoClient();
c.sendAndReceive(checkRead);
}
}
}
public class IntermediateHost {
DatagramSocket receiveFromClient, receiveFromServer;
DatagramPacket receiveClientPack, sendClientPacket, receiveServerPacket, sendServerPacket;
public IntermediateHost() {
try {
receiveFromClient = new DatagramSocket(5000);
} catch (SocketException e) {
e.printStackTrace();
}
}
public void receiveAndEcho() {
byte [] b = new byte[100];
//When we receive the packet we need to store it in a datagrampacket which is initally empty
receiveClientPack = new DatagramPacket(b, b.length);
InetAddress ip = null;
try {
receiveFromClient.receive(receiveClientPack);
ip = InetAddress.getByName("localhost");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
String message = new String(b);
System.out.println(message);
System.out.println(b);
int port = 3001;
sendClientPacket = new DatagramPacket(b, b.length, ip, port);
try {
receiveFromClient.send(sendClientPacket);
} catch (IOException e1) {
e1.printStackTrace();
}
receiveFromClient.close();
//SEND BACK TO THE CLIENT
try {
Thread.sleep(5000);
receiveFromServer = new DatagramSocket(3001);
} catch (InterruptedException | SocketException e1) {
e1.printStackTrace();
}
byte [] b1 = new byte[4];
//When we receive the packet we need to store it in a datagrampacket which is initally empty
receiveServerPacket = new DatagramPacket(b1, b1.length);
//This method will wait for the incoming packet and it will copy all values from that packet
//into receiveClientPack..so at this point the byte array will not be empty
try{
receiveFromServer.receive(receiveServerPacket);
}catch (Exception e) {
System.out.println(e);
}
for(int i =0;i < b1.length; i++) {
System.out.println(b1[i] & 0xff);
}
InetAddress ip1 = null;
try {
ip1 = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
int port1 = 5000;
sendServerPacket = new DatagramPacket(b1, b1.length, ip1, port1);
try {
receiveFromServer.send(sendServerPacket);
} catch (IOException e) {
e.printStackTrace();
}
receiveFromServer.close();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String args[]) throws IOException, InterruptedException {
while(true) {
IntermediateHost inter = new IntermediateHost();
inter.receiveAndEcho();
}
}
}
public class SimpleEchoServer {
DatagramPacket sendPacket, receivePacket;
DatagramSocket sendSocket, receiveSocket;
public SimpleEchoServer()
{
try {
sendSocket = new DatagramSocket();
receiveSocket = new DatagramSocket(3001);
} catch (SocketException se) {
se.printStackTrace();
System.exit(1);
}
}
public byte[] sendBackRead() {
byte [] bytesToSend = new byte[4];
bytesToSend[0] = 0x00;
bytesToSend[1] = 0x03;
bytesToSend[2] = 0x00;
bytesToSend[3] = 0x01;
return bytesToSend;
}
public byte[] sendBackWrite() {
byte [] bytesToSend = new byte[4];
bytesToSend[0] = 0x00;
bytesToSend[1] = 0x04;
bytesToSend[2] = 0x00;
bytesToSend[3] = 0x00;
return bytesToSend;
}
public boolean checkRead(byte[] msg) {
if(msg[1] == 1) {
return true;
}
return false;
}
public boolean checkWrite(byte[] msg) {
if(msg[1] == 2) {
return true;
}
return false;
}
public void receiveAndEcho() throws UnknownHostException
{
byte data[] = new byte[100];
receivePacket = new DatagramPacket(data, data.length);
System.out.println("Server: Waiting for Packet.\n");
try {
System.out.println("Waiting..."); // so we know we're waiting
receiveSocket.receive(receivePacket);
} catch (IOException e) {
System.out.print("IO Exception: likely:");
System.out.println("Receive Socket Timed Out.\n" + e);
e.printStackTrace();
System.exit(1);
}
boolean checkRead = checkRead(data);
boolean checkWrite = checkWrite(data);
String message = new String(data);
System.out.println(message);
receiveSocket.close();
// Slow things down (wait 5 seconds)
try {
Thread.sleep(5000);
} catch (InterruptedException e ) {
e.printStackTrace();
System.exit(1);
}
byte[] bytesToSend = null;
System.out.println(data[1]);
if(checkRead) {
bytesToSend = sendBackWrite();
}else if(checkWrite) {
bytesToSend = sendBackRead();
}
for(int i =0;i < bytesToSend.length; i++) {
System.out.println(bytesToSend[i] & 0xff);
}
InetAddress ip = InetAddress.getLocalHost();
sendPacket = new DatagramPacket(bytesToSend, bytesToSend.length,
ip, 3001);
// Send the datagram packet to the client via the send socket.
try {
sendSocket.send(sendPacket);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
System.out.println("Server: packet sent");
// We're finished, so close the sockets.
sendSocket.close();
receiveSocket.close();
}
public static void main( String args[] ) throws UnknownHostException
{
while(true) {
SimpleEchoServer c = new SimpleEchoServer();
c.receiveAndEcho();
}
}
}
现在这个代码可以工作,如果我只发送一个数据包到主机,主机发送到服务器,从主机返回另一个数据包到客户端。但是当我尝试发送超过一个数据包我收到一个错误。为了发送多个数据包,我基本上在main中创建一个循环,简单地调用方法11次,然后在服务器和主机中放置一个while循环,让它连续运行以等待数据包。要查看它运行一次,只需消除所有三个类的main函数中的while循环。
非常感谢有关如何修复此错误的任何帮助!谢谢!
答案 0 :(得分:1)
每次调用SimpleEchoClient c = new SimpleEchoClient();
时,您的代码都会尝试在端口5000上创建客户端。由于您已在同一端口上运行客户端,因此抛出异常。
所以只做一次并发送数据包11次。
public static void main(String args[])
{
boolean checkRead = true;
int count =0;
SimpleEchoClient c = new SimpleEchoClient();
for(int i = 0; i<=10; i++) {
System.out.println("Count:" + count);
c.sendAndReceive(checkRead);
}
}
检查我如何将循环条件更改为<=10
以确保发送了11个数据包。