在客户端JAVA中调用socket.close()时套接字未关闭服务器端

发布于 2024-09-10 12:47:33 字数 1893 浏览 5 评论 0原文

我在使用 java 套接字时遇到问题。我有一个 ServerSocket 正在监听accept() 并为每个客户端请求生成线程。客户端和服务器之间的通信工作正常。我正在使用输入流从服务器线程中的客户端读取数据,例如:

inputStream = mySocket.getInputStream();
bytes = inputStream.read(buffer);

我的问题是,如果我从客户端调用 socket.close() ,则 bytes = inputStream.read(buffer) 的阻塞调用不会发生任何事情;,它继续阻塞。但如果我从服务器关闭套接字,那么客户端的 inputStream.read(buffer); 就会返回“-1”。

服务器-主线程:

//SERVER MAIN THREAD, SPAWNS CLIENT THREADS
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (listening){

new ServerThread(serverSocket.accept(), monitor).start();
}

服务器-客户端线程:

public class ServerThread extends Thread{

public ServerThread(Socket socket, Monitor monitor) {
        this.socket = socket;
        this.monitor = monitor;
    }

    public void run(){
        byte[] buffer = new byte[1024];
        int bytes;
        //Listen
        while(true){
            try {
                InputStream inputStream = socket.getInputStream();
                monitor.doStuffWithOtherThreads(Object myObject);
                bytes = inputStream.read(buffer); //Problem
                if (bytes == -1){
                    System.out.println("breaks");
                    break;
                }

                byte[] readBuf = (byte[]) buffer;
                String readMessage = new String(readBuf, 0, bytes);
                System.out.println(readMessage);
                System.out.println(bytes);


            } catch (IOException e) {
                System.out.println("Connection closed");
                break;
            }
        }
    }

客户端:

InetAddress serverAddr = InetAddress.getByName("serverhostname");

socket = new Socket(serverAddr, PORT);

socket.close(); //Close the socket connection from client. Nothing happens in the serverthread

I'm having problems with sockets in java. I have a ServerSocket that is listening with accept() and spawns threads for each client-request. Communication between clients and the server works fine. I am using an inputstream to read data from clients in the serverthreads, like:

inputStream = mySocket.getInputStream();
bytes = inputStream.read(buffer);

My problem is that if I call socket.close() from the clients, nothing happens to the blocking call of bytes = inputStream.read(buffer);, it continues to block. But it works if I close the socket from the server, then the inputStream.read(buffer); of the client returns "-1".

SERVER-MAINTHREAD:

//SERVER MAIN THREAD, SPAWNS CLIENT THREADS
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
while (listening){

new ServerThread(serverSocket.accept(), monitor).start();
}

SERVER-CLIENTTHREADS:

public class ServerThread extends Thread{

public ServerThread(Socket socket, Monitor monitor) {
        this.socket = socket;
        this.monitor = monitor;
    }

    public void run(){
        byte[] buffer = new byte[1024];
        int bytes;
        //Listen
        while(true){
            try {
                InputStream inputStream = socket.getInputStream();
                monitor.doStuffWithOtherThreads(Object myObject);
                bytes = inputStream.read(buffer); //Problem
                if (bytes == -1){
                    System.out.println("breaks");
                    break;
                }

                byte[] readBuf = (byte[]) buffer;
                String readMessage = new String(readBuf, 0, bytes);
                System.out.println(readMessage);
                System.out.println(bytes);


            } catch (IOException e) {
                System.out.println("Connection closed");
                break;
            }
        }
    }

CLIENT:

InetAddress serverAddr = InetAddress.getByName("serverhostname");

socket = new Socket(serverAddr, PORT);

socket.close(); //Close the socket connection from client. Nothing happens in the serverthread

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清旖 2024-09-17 12:47:33

您发布的服务器代码不检查-1。因此,要么这就是问题所在,要么这不是真正的代码,在这种情况下,您应该发布真实代码进行评论。

编辑您发布的代码的行为与您所描述的不同。

The server code you posted doesn't check for -1. So either that is the problem or that isn't the real code, in which case you should post the real code for comment.

EDIT The code you have posted does not behave as you have described.

违心° 2024-09-17 12:47:33

在你的 Android 客户端代码中尝试一下:

socket.shutdownOutput(); 
socket.close(); 

应该会更好;-)

Try this in your Android client code :

socket.shutdownOutput(); 
socket.close(); 

It should be better ;-)

静谧 2024-09-17 12:47:33

我不知道我是否理解你的问题,但我想说,由服务器关闭套接字是正常的。

在服务器端(在独立线程中),您有侦听套接字:

ServerSocket socketServeur = new ServerSocket(port);

然后可能(在同一线程中,如果它是小型服务器)接受传入连接的循环(没有异常管理,可能socket.close位于finally块中) :

while (! askedToClose) {
    Socket socket = socketServeur.accept();
    doSomethingWithRequest(socket);
    socket.close();
}

在客户端,您有:

Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(port));
OutputStream output = clientSocket.getOutputStream();
// send something to server
InputStream input = clientSocket.getInputStream(); // will block until data is available
// reading response

服务器应该知道它何时到达请求末尾。例如在http中它可能是(取自scala中的mockHttpServer,因此可能会出现一些错误,但过程是相同的):

void doSomethingWithRequest(Socket socket) {
    BufferedReader inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream));
    StreamWriter outputWriter = new OutputStreamWriter(socket.getOutputStream);

    StringBuilder requestBuilder = new StringBuilder();
    do {
        requestBuilder.append(inputReader.read().toChar());
    } while (!requestBuilder.toString().endsWith("\r\n\r\n"));

    saveUri(getUriFromRequest(requestBuilder.toString()));

    outputWriter.write("HTTP/1.1 200 OK\r\n\r\n");
    outputWriter.flush();

    inputReader.close();
    outputWriter.close();
}

编辑:
我读了添加的代码,但仍然不明白:

  • 您调用 Socket.close(),但此方法不是静态的,
  • 您在“服务器”中永远循环
  • 我的印象是您对客户端和服务器使用相同的套接字

你有3个“套接字”:

  • 监听套接字(ServerSocket对象)
  • 接受套接字(由socketServer.accept()发送的对象套接字)
  • 客户端套接字(如上面的示例)

服务器打开和关闭监听和“接受”套接字,并且不应受到不良客户端套接字管理的影响。

然后,如果您希望服务器接受多个并发连接,您可以添加一个线程池来接受连接并处理请求和响应。

I don't know if I understand your issue, but I would say that it is normal that it's up to the server to close the socket.

On server side (in an independent thread) you have the listening socket :

ServerSocket socketServeur = new ServerSocket(port);

Then probably (in the same thread if it is a small server) a loop accepting incoming connections (no exception management, probably the socket.close is in a finally block) :

while (! askedToClose) {
    Socket socket = socketServeur.accept();
    doSomethingWithRequest(socket);
    socket.close();
}

On the client side, you have :

Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(port));
OutputStream output = clientSocket.getOutputStream();
// send something to server
InputStream input = clientSocket.getInputStream(); // will block until data is available
// reading response

The server should know when it has reached the end of the request. For example in http it could be (taken from a mockHttpServer in scala so there might be some errors but the process is the same):

void doSomethingWithRequest(Socket socket) {
    BufferedReader inputReader = new BufferedReader(new InputStreamReader(socket.getInputStream));
    StreamWriter outputWriter = new OutputStreamWriter(socket.getOutputStream);

    StringBuilder requestBuilder = new StringBuilder();
    do {
        requestBuilder.append(inputReader.read().toChar());
    } while (!requestBuilder.toString().endsWith("\r\n\r\n"));

    saveUri(getUriFromRequest(requestBuilder.toString()));

    outputWriter.write("HTTP/1.1 200 OK\r\n\r\n");
    outputWriter.flush();

    inputReader.close();
    outputWriter.close();
}

EDIT :
I read the code added and I still don't get it :

  • you call Socket.close(), but this method is not static
  • you loop forever in the "server"
  • I have the impression that you use the same socket for client and server

You have 3 "sockets" :

  • the listening socket (object ServerSocket)
  • the accept socket (Object Socket sent by socketServer.accept())
  • the client socket (like above in the example)

The server open and close listening and "accept" socket, and should have no impact of bad client socket management.

Then if you want your server to accept several concurrent connections, you may add a ThreadPool for accepting connections and treating requests and responses.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文