这段代码有什么问题..?Java 套接字编程



我正在使用java,套接字编程编写客户端 - 服务器多线程计算器。 存在任何语法错误,但无法从服务器接收消息。

我认为

receiveString = inFromServer.readLine()

不起作用。此代码位于客户端程序中,在 while(true) 循环中。

问题出在哪里? 这是我的完整代码。

SERVER
import java.io.*;
import java.net.*;
public class Server implements Runnable 
{
static int max = 5; //maximum thread's number
static int i = 0, count = 0; //i for for-loop, count for count number of threads
public static void main(String args[]) throws IOException 
{
ServerSocket serverSocket = new ServerSocket(6789); //open new socket
File file = new File("src/serverinfo.dat"); //make data file to save server info.
System.out.println("Maximum 5 users can be supported.nWaiting...");
for(i=0; i <= max; i++) { new Connection(serverSocket); } //make sockets - loop for max(=5) times
try //server information file writing
{ 
String dataString = "Max thread = 5nServer IP = 127.0.0.1nServer socket = 6789n";
@SuppressWarnings("resource")
FileWriter dataFile = new FileWriter(file);
dataFile.write(dataString);
}
catch(FileNotFoundException e) { e.printStackTrace(); }
catch(IOException e) { e.printStackTrace(); }
}

static class Connection extends Thread
{
private ServerSocket serverSocket;
public Connection(ServerSocket serverSock)
{
this.serverSocket = serverSock;
start();
}
public void run()
{ 
Socket acceptSocket = null;
BufferedReader inFromClient = null;
DataOutputStream msgToClient = null;
String receiveString = null;
String result = "", sys_msg = "";
try
{
while(true)
{
acceptSocket = serverSocket.accept(); // 접속수락 소켓
count++;
inFromClient = new BufferedReader(new InputStreamReader(acceptSocket.getInputStream()));
msgToClient = new DataOutputStream(acceptSocket.getOutputStream());
System.out.println(count + "th client connected: " + acceptSocket.getInetAddress().getHostName() + "    " + count + "/" + max);
System.out.println("Waiting response...");
while(true)
{
if (count >= max+1) // if 6th client tries to access
{
System.out.println("Server is too busy. " + max + " clients are already connected. Client access denied.");
sys_msg = "DENIED";
msgToClient.writeBytes(sys_msg);
acceptSocket.close();
count--;
break;
}
try{ msgToClient.writeBytes(result); }
catch(Exception e) {}
try{ receiveString = inFromClient.readLine(); }
catch(Exception e) // if receiveString = null
{
System.out.println("Connection Close");
count--;
break;
}
System.out.println("Input from client : " + receiveString);
try
{       
if(receiveString.indexOf("+") != -1) { result = cal("+", receiveString); }
else if(receiveString.indexOf("-") != -1) { result = cal("-", receiveString); }
else if(receiveString.indexOf("/") != -1) { result = cal("/", receiveString); }
else if(receiveString.indexOf("*") != -1) { result = cal("*", receiveString); }
else if(receiveString.indexOf("+") == -1 || receiveString.indexOf("-") == -1 || receiveString.indexOf("*") == -1 || receiveString.indexOf("/") == -1) { result = "No INPUT or Invalid operation"; }
}
catch(Exception e){ result = "Wrong INPUT"; }
try{ msgToClient.writeBytes(result); }
catch(Exception e) {}
}
}
}
catch(IOException e) { e.printStackTrace(); }
}
}
private static String cal(String op, String recv) //function for calculating
{
double digit1, digit2; //first number, second number
String result = null;
digit1 = Integer.parseInt(recv.substring(0, recv.indexOf(op)).trim());
digit2 = Integer.parseInt(recv.substring(recv.indexOf(op)+1, recv.length()).trim());
if(op.equals("+")) { result = digit1 + " + " + digit2 + " = " + (digit1 + digit2); }
else if(op.equals("-")) { result = digit1 + " - " + digit2 + " = " + (digit1 - digit2); }
else if(op.equals("*")) { result = digit1 + " * " + digit2 + " = " + (digit1 * digit2); }
else if(op.equals("/"))
{
if(digit2 == 0){ result = "ERROR OCCURRED: Cannot be divided by ZERO"; }
else{ result = digit1 + " / " + digit2 + " = " + (digit1 / digit2); }
}
return result;
}
@Override
public void run() {
//    TODO Auto-generated method stub
}
}
-----------------------------------------------------------------
CLIENT
import java.io.*;
import java.net.*;
public class Client {
public static void main(String args[]) throws IOException
{
Socket clientSocket = null;
BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in));
BufferedReader inFromServer = null;
DataOutputStream msgToServer = null;
String sendString = "", receiveString = "";
try
{
clientSocket = new Socket("127.0.0.1", 6789); //make new clientSocket
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
msgToServer = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Input exit to terminate");
System.out.println("Connection Success... Waiting for permission");
while(true)
{
receiveString = inFromServer.readLine();
if(receiveString.equals("DENIED"))
{
System.out.println("Server is full. Try again later.");
break;
}
else { System.out.println("Connection permitted."); }
System.out.print("Input an expression to calculate(ex. 3+1): ");
sendString = userInput.readLine();
if(sendString.equalsIgnoreCase("exit")) //when user input is "exit" -> terminate
{
clientSocket.close();
System.out.println("Program terminated.");
break;
}
try { msgToServer.writeBytes(sendString); }
catch(Exception e) {}
try { receiveString = userInput.readLine(); }
catch(Exception e) {}
System.out.println("Result: " + receiveString); //print result
}
}
catch(IOException e)
{
e.printStackTrace();
}
}
}

您设置了错误的服务器套接字堆栈。

您的代码将创建 5 个线程,每个调用在服务器套接字上接受。

这个想法是有一个ServerSocket(而不是像你的例子中那样有 5 个)。然后,这个单个 serversocket(在处理从此 serversocket 流出的传入套接字的单个线程中运行)将调用.accept,它将阻塞(冻结线程),直到建立连接,然后返回一个Socket对象。然后,您将剥离一个线程来处理套接字对象,并直接返回到accept调用。如果你想"池"(这不是一个坏主意),那么将"处理连接"的概念与"扩展线程"分开。例如,改为实现 Runnable。然后预先创建整个池(例如,10 个线程),有一些代码可以让您从池中"抓取线程"并将线程"返回"到池中,现在 serversocket 线程将在accept返回套接字对象时从池中获取一个线程(这将阻塞,因此也会阻止任何传入的客户端, 如果池中的每个线程都已被取出并忙于处理连接),直到线程返回到池中。或者,serversocket 代码检查池是否完全耗尽,如果是,则将在最后一个线程上放置响应该客户端"不可以做,我们现在已满"的工作。

我不确定你是否真的想要那个;只是..每个传入套接字制作1个线程要简单得多。在您真正需要之前,我不会深入研究池概念,如果您确实需要,我会寻找有助于管理它们的库。我认为关于这个问题的进一步建议超出了这个问题的范围,所以我将第一段作为ServerSocket代码应该如何工作的支出,作为上下文。

最新更新