Search code examples
javasocketsclient-serverjava-client

JAVA socket closed down before it Accepts data


I am unable to send data from the server(python) to the client (android java). Java client socket gets shutdown before it accepts data from the server.

no Error on the Python side it sends data as well but the java client socket is closed and doesn't accept data

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 code

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 codee

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");

Solution

  • In your java code you have the lines

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

    That last line out.close(); also closes the socket. This may not be obvious. DataOutputStream extends FilterOutputStream and inherits its close method. FilterOutputStream.close() also closes the wrapped OutputStream which in this case is socket.getOutputStream(). The Javadocs for socket.getOutputStream() state

    Closing the returned OutputStream will close the associated socket.

    Since your python code reads until end-of-stream/end-of-file, you need some way for Java signal to signal to its python peer that it is finished writing data. Java provides this through the socket.shutdownOutput() method. Thus, if you replace out.close(); with socket.shutdownOutput() you should get the effect you need:

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