Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 简单客户端-服务器应用程序-套接字问题_Java_Sockets_Client Server - Fatal编程技术网

Java 简单客户端-服务器应用程序-套接字问题

Java 简单客户端-服务器应用程序-套接字问题,java,sockets,client-server,Java,Sockets,Client Server,我正在使用TCP套接字编写一个简单的客户机-服务器应用程序。它使用多线程原理,允许多个客户端连接到同一台服务器 我在找出套接字中的一些错误时遇到了一些困难,您可能会告诉我,我在这个环境中是相当新的 我将向您展示我拥有的代码以及从中获得的输出,但基本上问题在于客户机与服务器的连接,我浏览了所有代码,但仍然找不到问题所在 服务器: public static ArrayList<String> userList = new ArrayList<String>(); publi

我正在使用TCP套接字编写一个简单的客户机-服务器应用程序。它使用多线程原理,允许多个客户端连接到同一台服务器

我在找出套接字中的一些错误时遇到了一些困难,您可能会告诉我,我在这个环境中是相当新的

我将向您展示我拥有的代码以及从中获得的输出,但基本上问题在于客户机与服务器的连接,我浏览了所有代码,但仍然找不到问题所在

服务器:

public static ArrayList<String> userList = new ArrayList<String>();
public static int index;
public static String date;
public static void main(String args[]) throws Exception {//inicio main      


    ServerSocket server = new ServerSocket(6500);   //Create socket on port 6500
    System.out.println ("Server started on port 6500");     
    while (true){   //Waiting for clients
        System.out.println("Server waiting for client connections..");
        Socket socket = null;
        BufferedReader reader = new BufferedReader(new FileReader("C:\\UNIV\\Redes\\workspace\\Copy of Ex_4.3_Teste\\lists\\blacklist.txt"));
        String line = null;
        socket = server.accept();

        // Blacklist verification
        while ((line = reader.readLine()) != null) {
            if (line.equals(socket.getInetAddress().toString())) {
                System.out.println("IP Blacklisted: " + socket.getInetAddress().toString());
                System.out.println("Closing connection to " + socket.getInetAddress().toString());
                PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
                checkBlack.println("***BLACKLISTED***");
                reader.close();
                checkBlack.close();
                socket.close();
                break; 
            }
        }//End of Blacklist Verification

        //Sending feedback in case of approved client
        try { 
        PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
        checkBlack.println("***NBLACKLISTED***");
        checkBlack.close();
        } catch (SocketException e) {

        }
        userList.add(socket.getInetAddress().toString()); //Add connected user's IP to USERLIST
        System.out.println("New connection..");
        System.out.println("Size of UserList: " + userList.size());
        Thread t = new Thread(new EchoClientThread(socket)); 

        t.start(); //Starting Client Thread


    }//End of Waiting for Clients       
}//End of Main  

public static class EchoClientThread implements Runnable{
    private Socket s;
    public EchoClientThread(Socket socket) {
        this.s = socket;
    }
    public void run() { 
        String threadName = Thread.currentThread().getName();   //Thread Name
        String stringClient = s.getInetAddress().toString();    //Client IP
        System.out.println("Connected to " + stringClient); 

        try{                
            BufferedReader input = new BufferedReader(
                    new InputStreamReader(s.getInputStream()));         
            PrintStream output = new PrintStream(
                    s.getOutputStream(),true);
            String line;
            while ((line = input.readLine()) !=null) {  //Input Cycle   

                System.out.println (stringClient+": "+threadName+": "+line);    //Print command from client

                if (line.equalsIgnoreCase("9")){ //Exit
                    break;
                }

                else if (line.equalsIgnoreCase("1")){   //Send List of Online Users
                    System.out.println("Option 1: Sending list of online users to " + stringClient);
                    output.println(" ");
                    output.println("List of Online Users:");
                    output.println(" ");
                    for(int i=0;i<userList.size();i++){
                        output.println(userList.get(i));
                    }
                }

                else if (line.equalsIgnoreCase("2")) {  //Send message to a single user
                    System.out.println("Nothing here yet..");
                }

                else if (line.equalsIgnoreCase("3")) {  //Send message to all the online users
                    System.out.println("Nothing here yet..");
                }

                else if (line.equalsIgnoreCase("4")){   //Send User Blacklist
                    System.out.println("Option 4: Sending user blacklist to " + stringClient);
                    BufferedReader reader = new BufferedReader(new FileReader("C:\\UNIV\\Redes\\workspace\\Copy of Ex_4.3_Teste\\lists\\blacklist.txt"));
                    String lineRead = null;
                    output.println(" ");
                    output.println("User Blacklist:");
                    output.println(" ");
                    while ((lineRead = reader.readLine()) != null) {
                        output.println(lineRead);
                    }
                    reader.close();
                }

                else{
                    output.println("Unknown command.");
                }   

                output.println("***CLOSE***");  //Closes client's input cycle
                output.println("***NBLACKLISTED***");   //Sending feedback in case of approved client                       
            }//Input Cycle End

            output.println("See you later!"); 
            input.close();  //Closes inputStream 
            output.close(); //Closes outputStream
            s.close();  //Closes Socket                         
        }
        catch (Exception e){
            System.err.println("Server Side Error!");
            System.out.println(e);
        }
        userList.remove(s.getInetAddress().toString());
        System.out.println("Client "+ stringClient+" was disconnected!");                   
    }//End of run()  
}//End of EchoClientThread
}//End of EchoServerThread
但只要我尝试与客户联系,就会发生以下情况:

服务器端:

Server started on port 6500
Server waiting for client connections..
New connection..
Size of UserList: 1
Server waiting for client connections..
Connected to /127.0.0.1
java.net.SocketException: Socket is closed
Server Side Error!
Client /127.0.0.1 was disconnected!
但在客户端,它仍然显示输入菜单和命令提示符,如下所示:

CLIENT MENU

1 - List on-line users
2 - Send message to a single user
3 - Send message to all on-line users
4 - List Blacklisted Users
9 - Exit

127.0.0.1:6500#>
当我在客户端提示符上输入内容时,我得到:

127.0.0.1:6500#>1
Client Side Error!
java.net.SocketException: Software caused connection abort: recv failed
Connection Terminated
我知道错误的意思,
套接字关闭了
几乎是不言自明的,但我就是找不到导致套接字关闭的代码问题


非常感谢您的帮助。

您的黑名单机制不太正确

当您关闭与套接字关联的流时,它也将关闭套接字

所以服务器关闭它获得的任何套接字,然后将其交给线程, 尝试使用套接字但失败

    // Blacklist verification
    while ((line = reader.readLine()) != null) {
        // blah blah blah
    }//End of Blacklist Verification

    //Sending feedback in case of approved client
    try { 
        PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
        checkBlack.println("***NBLACKLISTED***");
        checkBlack.close();  // <== why are you closing the stream?
    } catch (SocketException e) {

    }

调试器是你的朋友。

你试过调试服务器代码吗?在我看来,您的服务器只是因为异常而关闭了套接字。如果您也可以发布异常,那么我得到的唯一异常是
java.net.SocketException:Socket在客户端尝试连接到服务器时关闭。但调试并没有帮到我,这也是我在这里问这个问题的部分原因。显然,它在
System.out.println(“连接到”+stringClient)
之后立即关闭套接字,但我不知道为什么。我想我需要关闭流,以便为命令输入打开一个新的流。好吧,我想那不是。每天都是学习日^^非常感谢。PrintStream将SocketStream包裹起来,这样您就可以挂起它了。除非希望基础流关闭,否则不要关闭。流可能会变得混乱,有些你必须关闭其他你必须离开的流。哦,我明白了,执行
socket.getOutputStream().write()
只写它必须写入的内容,然后关闭流而不关闭套接字?不,流保持打开状态。创建套接字时,您将创建一个上游(out)和一个下游(in)。每个插座只能有一个,因此它们需要在插座的使用寿命内保持打开状态。当您需要发送或接收某些内容时,您只需获得适当的流并进行读写。无论何时在套接字上调用get***Stream,您都会得到***的相同流,如果有多个线程使用同一套接字,这一点很重要。当套接字关闭时,流将为您清理。这有点令人困惑,但我想我现在明白了,感谢您花时间:)
127.0.0.1:6500#>1
Client Side Error!
java.net.SocketException: Software caused connection abort: recv failed
Connection Terminated
    // Blacklist verification
    while ((line = reader.readLine()) != null) {
        // blah blah blah
    }//End of Blacklist Verification

    //Sending feedback in case of approved client
    try { 
        PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
        checkBlack.println("***NBLACKLISTED***");
        checkBlack.close();  // <== why are you closing the stream?
    } catch (SocketException e) {

    }
    // Blacklist verification
    while ((line = reader.readLine()) != null) {
        // blah blah blah
    }//End of Blacklist Verification

    //Sending feedback in case of approved client
    try { 
        socket.getOutputStream().write("***NBLACKLISTED***\n".getBytes());
    } catch (SocketException e) {
        e.printStackTrace();
    }