JAVA 套接字在接受数据之前关闭

JAVA socket closed down before it Accepts data

我无法将数据从服务器(python) 发送到客户端(android java)。 Java 客户端套接字在接受来自服务器的数据之前关闭。

在 Python 端没有错误它也发送数据但是 java 客户端套接字已关闭并且不接受数据

Error W/System.err: java.net.SocketException: Socket is closed at java.net.Socket.getInputStream(Socket.java:923) W/System.err: at com.example.smd.TcpDataHandler.doInBackground(TcpDataHandler.java:66) at com.example.smd.TcpDataHandler.doInBackground(TcpDataHandler.java:20)

python代码

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    server_socket.bind(('ip' , port))
    server_socket.listen(10)
    print("server is listening")
    (client_socket,client_adress) = server_socket.accept()
    print("Socket completed")
    #client_socket.shutdown(socket.SHUT_WR)
    #while True:
    print('waitingg.....................')
    try:
        data2=b''
        while True:
            buf = client_socket.recv(65535)
            data2 += buf 
            if not buf:
                break
    
        client_input = data2
        print("data recieve ")

        b=base64.b64decode(client_input)
        #print(b)
        imageStream = io.BytesIO(client_input)
        imageFile = Image.open(imageStream)

        # i = Image.fromarray(imageFile, mode='L').convert('1')
        imageFile.LOAD_TUNCATED_IMAGES=True

        print(imageFile.size) 
        
        #this is the image ,here you cna verify via image size
        modelRes=test(imageFile)
        modelRes=modelRes[0]
        modelRes= int(modelRes[0])

        data = database(decode(imageFile))
        
        print(data)
        #json_obj = [{ "model_res": modelRes , "decode_data": data}]
        x = { "model_res": modelRes, "decode_res": data}
        
        # convert into JSON:
        data = json.dumps(x)
        print('data is : '+data)

        client_socket.send(data.encode())
        
        print('data sended')
        client_socket.shutdown(socket.SHUT_WR)
        
        print('Reciving BYE message')
        data3 = client_socket.recv(1024).decode()

        print('Program ended : '+data3)

        client_socket.close()
        server_socket.close()
    except Exception as e:
        print(e)

JAVA 码农

socket=new Socket("ip", port);
        System.out.println("Socket donee : ");


        byte[] bArray = new byte[(int) file.length()];
        try{
            fis = new FileInputStream(file);
            fis.read(bArray);
            fis.close();
        }catch(IOException ioExp){
            ioExp.printStackTrace();
        }


        Log.d("Data to bytes"," images has been converted to byte");
        out = new DataOutputStream(socket.getOutputStream());
        out.write(bArray);
        out.flush();
        out.close();

        Log.d("Data send"," Data has been send Successfully");

        Log.d("waiting responce"," Waiting ford data from Python");

        InputStreamReader streamReader= new 
        InputStreamReader(socket.getInputStream());
        BufferedReader reader= new BufferedReader(streamReader);
        String value= reader.readLine();
        System.out.println(value);
        Log.d("Data Revieve"," Recieve data Successfully");

        reader.close();
        dataRec="";
        dataRec=value;


        OutputStream outputStream = socket.getOutputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
        System.out.println("Sending BYE MSG");
        // write the message we want to send
        dataOutputStream.writeUTF("Byeee serverrrrrr");
        dataOutputStream.flush(); // send the message
        dataOutputStream.close(); // close the output stream when we're done.

        socket.close();
        Log.d("Socket closed "," Socket has been Successfully");

在您的 java 代码中有行

out = new DataOutputStream(socket.getOutputStream());
out.write(bArray);
out.flush();
out.close();

最后一行 out.close(); 也关闭了套接字。这可能并不明显。 DataOutputStream 扩展了 FilterOutputStream 并继承了它的关闭方法。 FilterOutputStream.close() 还会关闭包装的 OutputStream,在本例中为 socket.getOutputStream()socket.getOutputStream() 状态

的 Java 文档

Closing the returned OutputStream will close the associated socket.

由于您的 python 代码一直读到 end-of-stream/end-of-file,您需要一些方法让 Java 向它的 python 对等方发送数据写入完成的信号。 Java 通过 socket.shutdownOutput() 方法提供此功能。因此,如果您将 out.close(); 替换为 socket.shutdownOutput(),您应该会得到所需的效果:

out = new DataOutputStream(socket.getOutputStream());
out.write(bArray);
out.flush();
socket.shutdownOutput();