2014-04-29 25 views
6

Tôi đang cố gắng đọc dữ liệu từ ổ cắm máy chủ từ máy khách trong Android.java.net.SocketException: sendto không thành công: EPIPE (Broken pipe) trên Android

Dưới đây là các đoạn mã mà tôi đang sử dụng:

Khách hàng (Trên Android trong JAVA)

DataOutputStream dataOutputStream = null; 
    DataInputStream dataInputStream = null; 
    try { 

     if (client.socket == null || !client.socket.isConnected()) 
      client.createSocket(); 

     // Get Input/Output stream for socket 
     dataOutputStream = new DataOutputStream(client.socket.getOutputStream()); 
     dataInputStream = new DataInputStream(client.socket.getInputStream()); 

     // Here RS is simple JAVA class that stores information about payload and response length 
     Log.d("Send", "Sending payload for pair " + RS.getc_s_pair() + " " + RS.getResponse_len()); 

     dataOutputStream.write(UtilsManager.serialize(RS.getPayload())); 

     // Notify waiting Queue thread to start processing next packet 
     if (RS.getResponse_len() > 0) { 
      Log.d("Response", "Waiting for response for pair " + RS.getc_s_pair() + " of " + RS.getResponse_len() + " bytes"); 

      int totalRead = 0; 

      byte[] buffer = new byte[RS.getResponse_len()]; 
      while (totalRead < RS.getResponse_len()) { 
       int bytesRead = dataInputStream.read(buffer, totalRead, RS.getResponse_len() - totalRead); 

       if (bytesRead < 0) { 
        throw new IOException("Data stream ended prematurely"); 
       } 
       totalRead += bytesRead; 
      } 
    } 

Server (Python)

 # Here request_len is the expected request size 
     while buffer_len < response_set.request_len: 
      new_data = connection.recv(min(self.buff_size, response_set.request_len-buffer_len)) 
      if not new_data: 
       return False 
      buffer_len += len(new_data) 

     # Send required response 
     for response in response_set.response_list: 
      try: 
       connection.sendall(str(response.payload)) 
      except: 
       return False 

Đôi khi , Tôi gặp lỗi trong khi tôi đang gửi tải trọng từ khách hàng trên dòng

 dataOutputStream.write(UtilsManager.serialize(RS.getPayload())); 

Lỗi tôi nhận được là:

java.net.SocketException: sendto failed: EPIPE (Broken pipe) 
    at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:506) 
    at libcore.io.IoBridge.sendto(IoBridge.java:475) 
    at java.net.PlainSocketImpl.write(PlainSocketImpl.java:507) 
    at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:46) 
    at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:269) 
    at java.io.DataOutputStream.write(DataOutputStream.java:98) 
    at java.io.OutputStream.write(OutputStream.java:82) 
    at com.rgolani.replay.tcp.TCPClientThread.run(TCPClientThread.java:56) 
    at java.lang.Thread.run(Thread.java:856) 
Caused by: libcore.io.ErrnoException: sendto failed: EPIPE (Broken pipe) 
    at libcore.io.Posix.sendtoBytes(Native Method) 
    at libcore.io.Posix.sendto(Posix.java:151) 
    at libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:177) 
    at libcore.io.IoBridge.sendto(IoBridge.java:473) 
    ... 7 more 

Tôi biết đây là một chút bối rối. Mã Python không được viết bởi tôi và tồn tại một trình khách python hoạt động mà không có bất kỳ lỗi nào. Tôi nhận được lỗi này chỉ trong mã JAVA của tôi.

Working Python Khách hàng

if self.sock is None: 
     self._connect_socket() 

    self.sock.sendall(tcp.payload) 

    buffer_len = 0 
    while tcp.response_len > buffer_len: 
     data = self.sock.recv(min(self.buff_size, tcp.response_len-buffer_len)) 
     buffer_len += len(data) 

Xin vui lòng cho tôi biết nếu bạn cần thêm thông tin.

Cảm ơn bạn.

Trả lời

0

Có lẽ tôi đang thiếu một điểm với vấn đề của bạn, nhưng tôi nghĩ rằng nó sẽ đẹp hơn để sử dụng đoạn mã Java này:

import java.io.ObjectOutputStream; 
import java.io.ObjectInputStream; 

ObjectOutputStream dataOutputStream = null; 
ObjectInputStream dataInputStream = null; 
try { 

    if (client.socket == null || !client.socket.isConnected()) 
     client.createSocket(); 

    // Get Input/Output stream for socket 
    dataOutputStream = new ObjectOutputStream (client.socket.getOutputStream()); 
    dataInputStream = new ObjectInputStream (client.socket.getInputStream()); 

    // Here RS is simple JAVA class that stores information about payload and response length 
    Log.d("Send", "Sending payload for pair " + RS.getc_s_pair() + " " + RS.getResponse_len()); 

    // You might consider using java.io.Serializable interface with the argument object 
    dataOutputStream.writeObject(UtilsManager.serialize(RS.getPayload())); 

    // Notify waiting Queue thread to start processing next packet 
    if (RS.getResponse_len() > 0) { 
     Log.d("Response", "Waiting for response for pair " + RS.getc_s_pair() + " of " + RS.getResponse_len() + " bytes"); 

     // Read a java.io.Serializable object from the stream. So you have to write a java.io.Serializable object into the stream. 
     Object o = dataInputStream.readObject(); 
    } 
} 

Hope this helps ...

1

Nếu bạn đang sử dụng sau đó setChunkedStreamingMode loại bỏ nó và sau đó nhìn thấy.Tôi nghĩ rằng tôi rất muộn nhưng điều này giải quyết vấn đề của tôi. Bạn có thể sử dụng chế độ trực tuyến cố định chiều dài.

+0

Tôi sử dụng 'setChunkedStreamingMode' vì [link] (http://stackoverflow.com/questions/9630430/upload-large-file-in-android-without-outofmemory-error). Và gặp phải điều này một lần. Đó là php của sever không cho phép chiều dài không cố định. Nó sẽ được giải quyết ở phía máy chủ và không cần phải loại bỏ mã trên máy khách. – Yeung

1

Lỗi đó xảy ra khi máy khách cố gắng ghi vào kết nối khi chương trình phụ trợ đã đóng nó. Theo mặc định, Android đặt thuộc tính Keep Alive thành true và sẽ sử dụng lại các kết nối ổ cắm cũ kể từ khi thiết lập kết nối là hoạt động tiêu thụ tài nguyên trong môi trường di động (bạn có thể kiểm tra nó bằng công cụ như fiddler). Cố gắng đặt tiêu đề Connection thành close hoặc gọi System.setProperty("http.keepAlive", "false"); để tắt Keep Alive và do đó buộc hệ thống tạo kết nối mới.

0

Trong trường hợp của tôi: client.createSocket(); không kết nối với bất kỳ máy chủ nào - chỉ cần tạo một ổ cắm. Vì vậy, sau này tôi phải client.connect (_sock_sddr_here_);

Cũng được kết nối() - kiểm tra câm vì nó là vĩnh viễn đúng sự thật.

Các vấn đề liên quan