【问题标题】:Server is not sending back an acknowledgment to Client服务器没有向客户端发送回确认
【发布时间】:2017-09-11 03:55:44
【问题描述】:

我在下面有我的服务器代码:

public void startServer() {
        ServerSocket listener = selectUnusedPortFromRange(1024, 65535);
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String command = null;
                    while (true) {
                        Socket socket = listener.accept();
                        System.out.println("Got a connection from: " + socket.getLocalPort());
                        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                        command = in.readLine();
                        System.out.println("GOT HERE"); //Not being printed out
                        if (command != null && !"".equals(command)) {
                            if ("connection".equals(command)) {
                                Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                                writer.write("success\n");
                                writer.flush();
                            }
                        }
                    }
                }
            }
        }
        t.start();
}

这是我的客户端:

public void makeConnection() {
    try {
        Socket socket = new Socket(IP, PORT);
        Writer writer = new PrintWriter(socket.getOutputStream(), true);
        writer.write("connection\n");
        BufferedReader socketRead = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String str;
        while ((str = socketRead.readLine()) != null) {
            if ("success".equals(str)) {
                System.out.println("Successfully saved all hosts to: " + listOfHosts.get(i));
                socketRead.close();
                socket.close();
                iStream.close();
                writer.close();
            }
        }
    }catch (Exception e) {
         System.out.println(e.getMessage());
    }
}

在客户端创建连接到服务器的套接字后,我将“连接”写入套接字的outputStream 并等待服务器返回确认成功。由于某种原因,没有与服务器建立连接。在服务器System.out.println("Got a connection from: " + socket.getLocalPort()); 中没有打印出这一行。

我做错了什么。我看不出来。当我尝试连接到我的服务器时,我没有抛出异常。

【问题讨论】:

  • 只是一个健全性检查...您的客户端是否使用与您的服务器绑定的相同端口?我不知道selectUnusedPortFromRange() 做了什么,但我猜它绑定到您指定范围内的随机未使用端口?确保您的客户端知道它绑定到哪个端口。
  • @cricket 是的,我刚刚注意到并更改了它。那是我的打字错误。我现在已将其更改为我帖子中的正确代码。
  • @cricket_007 是的,我已经遵循了那个 turoial。
  • @1290 他们需要使用相同的端口。您的客户端正在尝试在它未侦听的端口上与服务器通信。

标签: java


【解决方案1】:

我面临着完全相同的问题。我通过使用 ACK 机制克服了它(不是我的想法,这是向我建议的)。这个想法是客户端将向服务器发出请求并保持套接字连接处于活动状态(并且输出流打开)直到服务器响应同意的 ACK 消息通过同一通道 .一旦客户端收到 ACK 消息,它才会关闭连接。

下面是服务器的代码:-

final ServerSocket listener = new ServerSocket(11111);
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                String command = null;
                 while (true) {
                    System.out.println("About to accept");
                    Socket socket = listener.accept();
                    System.out.println("Got a connection from: " + socket.getLocalPort());
                    DataInputStream inputStream = new DataInputStream(socket.getInputStream());
                    StringBuilder str = new StringBuilder(inputStream.readUTF());
                    //command = in.readLine();
                    System.out.println("GOT HERE. Msg received : "+str); 
                    if (str != null && !"".equals(str.toString())) {
                        command = str.toString();
                        if ("connection".equals(command)) {
                            System.out.println("Got connection message");
                             DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
                            outputStream.writeUTF("connection");
                            outputStream.close();

                        }
                    }
                    inputStream.close();
                    System.out.println("Done");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
        }
});
    t.start();

}

客户:-

public void makeConnection() {
    try {
        System.out.println("In makeConnection");
        Socket socket = new Socket("127.0.0.1", 11111);
        DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
        outputStream.writeUTF("connection");
        InputStream inputStream = socket.getInputStream();
        DataInputStream dataInputStream = new DataInputStream(inputStream);
        StringBuilder str;
        do {
            str = new StringBuilder(dataInputStream.readUTF()); 
            } while (!str.toString().equals("connection"));
        System.out.println("Successfully saved all hosts to: ");
        outputStream.close();
        dataInputStream.close();
        socket.close();
        outputStream.close();
    }catch (Exception e) {
         System.out.println(e.getMessage());
    }
}

启动程序的调用:-

public void start() throws IOException, InterruptedException {
    System.out.println("Starting server");
    startServer();
    Thread.sleep(1000);
    System.out.println("Starting connection");
    makeConnection();
}

【讨论】:

    【解决方案2】:

    1) 确保客户端和服务器使用相同的端口。它们必须通过同一个端口进行通信。您目前可能正在使用不同的端口。

    2) 确保您确实启动了您的服务器线程。在上面的代码中,您创建了一个新线程,但从不启动它。 t.start() 必须在某个地方调用。

    3) 如果这是在您的本地计算机上,您最好使用localhost 而不是实际的 IP 地址。防火墙可能会以不同的方式处理您的外部 IP。

    4) 使用换行符终止您的消息,例如\n,以便您的BufferedReader 可以使用它的readLine() 方法。为了更好地衡量,还可以通过刷新作者的缓冲区来跟进,以防换行符没有触发它。 writer.flush();

    最后,确保在再次尝试运行代码之前终止 JVM。您的代码没有关闭机制来从端口取消绑定服务器......因此您可能会抛出异常,告诉您端口和/或地址已在使用中。如果发生这种情况,要么更改端口,要么终止在后台运行的 java 进程。

    这是您的代码,稍作修改以在我的系统上运行。它正在按照您的预期工作。我试图尽可能少地改变,只是为了让它在我的系统上运行。需要注意的是,我将端口号硬编码到服务器和客户端中 - 这不是必需的,只是为了方便我进行测试:

    import java.io.BufferedReader;
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    import java.io.Writer;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Test {
        public static void main(String[] args) throws IOException {
            Test test = new Test();
            test.startServer();
            test.makeConnection();
        }
    
        public void startServer() throws IOException {
            final ServerSocket listener = new ServerSocket(60001);
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        String command = null;
                        while (true) {
                            Socket socket = listener.accept();
                            System.out.println("Got a connection from: " + socket.getLocalPort());
                            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                            command = in.readLine();
                            System.out.println("GOT HERE");
                            if (command != null && !"".equals(command)) {
                                if ("connection".equals(command)) {
                                    Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                                    writer.write("success\n");
                                    writer.flush();
                                }
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            t.start();
        }
    
        public void makeConnection() {
            System.out.println("Making Connection");;
            try {
                Socket socket = new Socket("localhost", 60001);
                Writer writer = new PrintWriter(socket.getOutputStream(), true);
                writer.write("connection\n");
                writer.flush();
                BufferedReader socketRead = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String str;
                while ((str = socketRead.readLine()) != null) {
                    if ("success".equals(str)) {
                        System.out.println("Successfully saved all hosts to: "); //+ listOfHosts.get(i));
                        socketRead.close();
                        socket.close();
                        //iStream.close();
                        writer.close();
                    }
                }
            }catch (Exception e) {
                 System.out.println(e.getMessage());
            }
        }
    
    }
    

    【讨论】:

    • 天啊,非常感谢。第 1 号被排除在外,第 2 号我忘了在我的问题(我的打字错误)中添加 t.start() 抱歉,第 3 号(没有防火墙),第 4 号是主要的,你的示例代码有很大帮助。谢谢!!
    • 现在还有一个问题.... 在我的服务器中,writer.write("success\n"); 部分没有被发送回客户端。它进入if ("connection".equals(command)) { } 块,但没有发回writer.write("success\n");
    • @1290 也许您的代码与我上面的代码有些不同?当我在我的系统上运行它时,显示“Successfully saved all hosts to: ”消息,这似乎是在客户端从服务器接收到success 消息时触发的。
    • 您确定您已修复您的服务器以发送"success\n" 吗?您的客户端中使用的readLine() 方法正在寻找换行符...
    • @1290 不用担心...我们都去过那里。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-05
    • 2015-02-10
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    相关资源
    最近更新 更多