简体   繁体   English

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

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

I am coding client-server multithread calculator using java, socket programming.我正在使用 java、套接字编程编写客户端-服务器多线程计算器。 There's any syntax error, but msgs cannot be received from server.有任何语法错误,但无法从服务器接收消息。

I think我认为

receiveString = inFromServer.readLine() receiveString = inFromServer.readLine()

does not works.不起作用。 This code is in Client program, in the while(true) loop.此代码在客户端程序中,在 while(true) 循环中。

What is the problem?问题是什么? Here is my full code.这是我的完整代码。

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();
        }
    }
}

You've set up your server socket stack wrong.您错误地设置了服务器套接字堆栈。

Your code will make 5 threads, each calling accept on a serversocket.您的代码将创建 5 个线程,每个线程在 serversocket 上调用 accept。

The idea is to have a single ServerSocket (and not 5, as in your example).这个想法是有一个ServerSocket (而不是 5,如您的示例)。 Then, this single serversocket (running in a single thread that handles incoming sockets flowing out of this serversocket) will call .accept which will block (freeze the thread) until a connection is made, and will then return a Socket object.然后,这个单一的 serversocket(在一个线程中运行,处理从这个 serversocket 流出的传入 sockets)将调用.accept ,它将阻塞(冻结线程)直到建立连接,然后将返回一个Socket object。 You'd then spin off a thread to handle the socket object, and go right back to the accept call.然后,您将分拆一个线程来处理套接字 object 和 go 回到accept调用。 If you want to 'pool' (which is not a bad idea), then disassociate the notion of 'handles connections' from 'extends Thread'.如果您想“池化”(这不是一个坏主意),则将“处理连接”的概念与“扩展线程”分离。 For example, implement Runnable instead.例如,改为实现 Runnable。 Then pre-create the entire pool (for example, 10 threads), have some code that lets you 'grab a thread' from the pool and 'return a thread' to the pool, and now the serversocket thread will, upon accept returning a socket object, grab a thread from the pool (which will block, thus also blocking any incoming clients, if every thread in the pool is already taken out and busy handling a connection), until a thread returns to the pool.然后预先创建整个池(例如,10 个线程),有一些代码可以让你从池中“抓取一个线程”并将一个线程“返回一个线程”到池中,现在 serversocket 线程将在accept返回一个socket object,从池中获取一个线程(如果池中的每个线程都已被取出并忙于处理连接,这将阻塞,因此也会阻塞任何传入的客户端),直到线程返回池。 Alternatively, the serversocket code checks if the pool is completely drained and if so, will put on a final thread the job of responding to that client 'no can do, we are full right now'.或者,serversocket 代码检查池是否已完全耗尽,如果是,将在最后一个线程上执行响应该客户端“不行,我们现在已经满了”的工作。

I'm not sure if you actually want that;我不确定你是否真的想要那个; just.. make 1 thread per incoming socket is a lot simpler.只是..为每个传入套接字创建 1 个线程要简单得多。 I wouldn't dive into pool concepts until you really need them, and if you do, I'd look for libraries that help manage them.在您真正需要它们之前,我不会深入研究池概念,如果需要,我会寻找有助于管理它们的库。 I think further advice on that goes beyond the scope of this question, so I'll leave the first paragraph as an outlay of how ServerSocket code ought to work, for context.我认为对此的进一步建议超出了这个问题的 scope,所以我将把第一段作为ServerSocket代码应该如何工作的支出,作为上下文。

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

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