繁体   English   中英

这段代码有什么问题……? Java插座编程

[英]What is the problem of this code…? Java socket programming

我正在使用 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 = 5\nServer IP = 127.0.0.1\nServer socket = 6789\n";
            @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 上调用 accept。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM