我正在开发Java项目,客户端通过DatagramSocket发送基本计算(例如5 + 6),服务器需要回复结果。目标是使用不同的线程计算每个不同的客户端请求。到目前为止,我有这段代码:
客户端:
import java.net.*;
import java.io.*;
public class UDPClient {
public static void main (String args[]){
DatagramSocket aSocket = null;
int input=-1;
String operation=null;
while(input!=0){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Select an option");
System.out.println("1. Do a basic calculation");
System.out.println("0. Exit ");
try{
input = Integer.parseInt(br.readLine());
if(input>1 | input<0)throw new Exception("Error");
}
catch(Exception e){
System.out.println("Wrong selection...Try again \n");
}
if(input==1)
{
System.out.println("Give operator symbol (+,-,*,/) ");
try{
String operator = br.readLine();
if(!(operator.matches("[*]|[+]|[/]|[-]")))throw new Exception("Error");
System.out.println("Give first number");
int first = Integer.parseInt(br.readLine());
System.out.println("Give second number");
int second = Integer.parseInt(br.readLine());
operation = first+":"+operator+":"+second;
send:
try{
aSocket = new DatagramSocket();
byte [] m = operation.getBytes();
InetAddress aHost = InetAddress.getByName(args[1]);
int serverPort = 6789;
DatagramPacket request = new DatagramPacket(m, m.length, aHost, serverPort);
aSocket.send(request);
aSocket.setSoTimeout(10000); // SocketTimeout happens here
byte[]buffer = new byte[1000];
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
aSocket.receive(reply);
System.out.println("Reply:" + new String(reply.getData()));
}
catch (SocketTimeoutException e) {
System.out.println("Server reply timeout");
break send; //If Timeout happens, send request again
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
finally {if (aSocket!=null) aSocket.close();}
}
catch(Exception e){
System.out.println("Wrong input...Try again \n");
}
}//End of if
}//end of while
}
}
服务器:
import java.net.*;
import java.nio.charset.Charset;
import java.io.*;
public class UDPServer {
static DatagramSocket aSocket = null;
public static void main (String args[]){
int i=0;
try{
aSocket = new DatagramSocket(6789);
byte[] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
aSocket.receive(request);
new ClientThread(aSocket,request);
}
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
}
}
class ClientThread extends Thread{
DatagramSocket sock;
DatagramPacket request;
public ClientThread(DatagramSocket sock, DatagramPacket request){
this.sock=sock;
this.request=request;
this.start();
}
public void run() {
try{
String input = new String(request.getData());
String[] in = input.split("[:]");
double temp=0;
if (in[1].matches("[+]")) temp = Double.valueOf(in[0])+Double.valueOf(in[2]);
if (in[1].matches("[-]")) temp = Double.valueOf(in[0])-Double.valueOf(in[2]);
if (in[1].matches("[*]")) temp = Double.valueOf(in[0])*Double.valueOf(in[2]);
if (in[1].matches("[/]")) temp = Double.valueOf(in[0])/Double.valueOf(in[2]);
String result ="Result: "+temp + " from Thread: "+ Thread.currentThread().getName() + "\n";
DatagramPacket reply = new DatagramPacket(result.getBytes(Charset.forName("UTF-8")),
result.length(),request.getAddress(),request.getPort());
//sock.send(reply);
System.out.println(result);
}
/*
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
*/
finally {}
}
}
我有两个基本问题
1)如果我从客户端发送第二个请求(第一个执行正常),则会导致服务器输出Socket关闭错误消息。
2)正如您所见,在服务器端,我当前评论了sock.send(回复),因此我可以查看我在客户端添加的超时代码。问题是超时发生后(由于没有发送回复)代码从头开始,而不是我在TimeoutException catch()中指定的发送标签。
如果有人能帮助我解决这两个问题,我会非常感激
提前感谢您的时间!!!
答案 0 :(得分:0)
在循环之前创建套接字。目前你正在让它被垃圾收集。
您在setSoTimeout()
调用时发生套接字超时的声明不正确。它发生在receive()
电话。
答案 1 :(得分:0)
修改后的代码似乎正在运行。让我知道你对此的看法
客户端:
import java.net.*;
import java.io.*;
public class UDPClient {
public static void main (String args[]){
DatagramSocket aSocket = null;
int input=-1; //User Input from menu
String operation=null; //keeps the calculation operation in String form
int resends=0; //NACK counter
while(input!=0){
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Select an option");
System.out.println("1. Do a basic calculation");
System.out.println("0. Exit ");
try{
input = Integer.parseInt(br.readLine());
if(input>1 | input<0)throw new Exception("Error");
}
catch(Exception e){
System.out.println("Wrong selection...Try again \n");
}
if(input==1)
{
System.out.println("Give operator symbol (+,-,*,/) ");
try{
String operator = br.readLine();
if(!(operator.matches("[*]|[+]|[/]|[-]")))throw new Exception("Error");
System.out.println("Give first number");
int first = Integer.parseInt(br.readLine());
System.out.println("Give second number");
int second = Integer.parseInt(br.readLine());
operation = first+":"+operator+":"+second;
}
catch(Exception e){
System.out.println("Wrong input...Try again \n");
System.out.println(e.getMessage());
}
while(true){
try{
if(resends==3){ // At 3 resends break loop
resends=0;
break;
}
aSocket = new DatagramSocket();
byte [] m = operation.getBytes();
InetAddress aHost = InetAddress.getByName(args[1]);
int serverPort = 6789;
DatagramPacket request = new DatagramPacket(m, m.length, aHost, serverPort);
aSocket.send(request);
resends++;//counting times we send this message
aSocket.setSoTimeout(30000); // Setting timeout for socket (30 sec)
byte[]buffer = new byte[1000];
DatagramPacket reply = new DatagramPacket(buffer, buffer.length);
aSocket.receive(reply);
System.out.println("Reply:" + new String(reply.getData()));
if(reply!=null)break; // If you get a reply, break loop
}
catch (SocketTimeoutException e) {
System.out.println("Server reply timeout");
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
finally {if (aSocket!=null) aSocket.close();}
}// end of send while loop
}//End of if
else if (input==0)
System.out.println("Exiting UDP Client.....");
}//end of while
}//end of main
}//end of Class
服务器:
import java.net.*;
import java.nio.charset.Charset;
import java.io.*;
public class UDPServer {
public static void main (String args[]){
DatagramSocket aSocket = null;
try{
aSocket = new DatagramSocket(6789);
byte[] buffer = new byte[1000];
while(true){
DatagramPacket request = new DatagramPacket(buffer, buffer.length);
aSocket.receive(request);
new ClientThread(aSocket,request);
}
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
finally {if(aSocket!=null)aSocket.close();}
}
}
class ClientThread extends Thread{
DatagramSocket sock;
DatagramPacket request;
public ClientThread(DatagramSocket sock, DatagramPacket request){
this.sock=sock;
this.request=request;
this.start();
}
public void run() {
try{
String input = new String(request.getData());
String[] in = input.split("[:]");
String result;
double temp=0;
if (in[1].matches("[+]")) temp = Double.valueOf(in[0])+Double.valueOf(in[2]);
if (in[1].matches("[-]")) temp = Double.valueOf(in[0])-Double.valueOf(in[2]);
if (in[1].matches("[*]")) temp = Double.valueOf(in[0])*Double.valueOf(in[2]);
if (in[1].matches("[/]")) temp = Double.valueOf(in[0])/Double.valueOf(in[2]);
result ="Result: "+temp + " from Thread: "+ Thread.currentThread().getName() + "\n";
DatagramPacket reply = new DatagramPacket(result.getBytes(Charset.forName("UTF-8")),
result.length(),request.getAddress(),request.getPort());
sock.send(reply);
//System.out.println(result);
}
catch(SocketException e){
System.out.println("Socket: " + e.getMessage());
}
catch(IOException e){
System.out.println("IO: " + e.getMessage());
}
}
}
在客户端,args [1]表示服务器的IP地址。如果您的服务器在Localhost上运行,则可以使用“127.0.0.1”。