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

Posted

技术标签:

【中文标题】JAVA套接字在接受数据之前关闭【英文标题】:JAVA socket closed down before it Accepts data 【发布时间】:2022-01-21 11:47:49 【问题描述】:

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

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

Error W/System.err: java.net.SocketException: Socket is closed 在 java.net.Socket.getInputStream(Socket.java:923) W/System.err: 在 com.example.smd.TcpDataHandler.doInBackground(TcpDataHandler.java:66) 在 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");

【问题讨论】:

socket 在这里关闭 InputStreamReader streamReader= new InputStreamReader(socket.getInputStream()); 如果我不关闭输出流 python 代码卡在 buf = client_socket.recv(65535) data2 += buf if not buf: break 非常感谢你hhhhhhhhhhhhhh你真的帮了我很多, 【参考方案1】:

在你的 java 代码中你有这些行

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

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

关闭返回的 OutputStream 将关闭关联的套接字。

由于您的 Python 代码一直读取到流结束/文件结束,因此您需要某种方式让 Java 信号向其 Python 对等方发出信号,表明它已完成写入数据。 Java 通过socket.shutdownOutput() 方法提供了这一点。因此,如果您将out.close(); 替换为socket.shutdownOutput(),您应该会得到您需要的效果:

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

【讨论】:

以上是关于JAVA套接字在接受数据之前关闭的主要内容,如果未能解决你的问题,请参考以下文章

通过接受关闭另一个线程中使用的套接字有啥风险?

在接受连接 C++ 之前获取套接字的 IP 地址

C |套接字不接受通过 telnet 的连接 [关闭]

关闭套接字会关闭流吗?

关闭套接字连接

socket中shutdown和closesocket的区别