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

时间:2017-04-14 20:57:12

标签: java

我的服务器代码如下:

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());中,此行未打印出来。

我做错了吗?我无法发现它。当我尝试连接到我的服务器时,我没有抛出异常。

2 个答案:

答案 0 :(得分:1)

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