Java 服务器未向客户端发回确认

Java 服务器未向客户端发回确认,java,Java,我的服务器代码如下: public void startServer() { ServerSocket listener = selectUnusedPortFromRange(1024, 65535); Thread t = new Thread(new Runnable() { @Override public void run() { try {

我的服务器代码如下:

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(“从:”+socket.getLocalPort()获得连接)中未打印出此行

我做错什么了吗。我看不出来。当我尝试连接到服务器时,不会引发异常。

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

}

我面临着完全相同的问题。我通过使用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();
}

只是一次精神检查。。。您的客户端使用的端口是否与服务器绑定到的端口相同?我不知道selectUnusedPortFromRange()的作用是什么,但我猜它会绑定到指定范围内的随机未使用端口?确保您的客户知道它绑定到哪个端口。@cricket是的,我刚刚注意到并更改了它。那是我打字的错误。我已经在我的帖子里把它改成了正确的代码。看到了吗@cricket_007是的,我遵循了turoial。@1290他们需要使用相同的端口。您的客户机正在尝试通过一个它没有监听的端口与服务器通话。OMG非常感谢。1号被排除在外,2号我忘了在我的问题(我的键入错误)中添加
t.start()
,很抱歉,3号(没有防火墙),4号是最主要的,您的示例代码帮助很大。非常感谢。现在还有一个问题。。。。在我的服务器中,
writer.write(“success\n”)部件未发送回客户端。它进入
if(“connection”.equals(command)){}
块,但它没有发回
writer.write(“success\n”)@1290也许你的代码和我上面的代码有些不同?当我在我的系统上运行它时,会显示“
成功地将所有主机保存到:
”消息,当客户端从服务器接收到
成功
消息时,该消息似乎会在客户端中触发。您确定已将服务器固定为发送
“成功\n”
?客户端使用的
readLine()
方法正在查找换行符…@1290不用担心。。。我们都去过那里