java.net.SocketException: sendto failed: EPIPE (Broken pipe) while sending byte[]

sourabh gupta picture sourabh gupta · Jan 20, 2014 · Viewed 7.1k times · Source

I am trying to upload video recorded through android mobile. but while sending video as byte[] to server I am getting below error :

  01-20 13:03:18.250: E/SaveMedia-response(4393): java.net.SocketException: sendto failed: EPIPE (Broken pipe)

Here is how I am trying to upload video :

        SoapObject request = new SoapObject(
                HelpMeConstant.WSDL_TARGET_NAMESPACE, "SaveMedia");
        Log.i("SaveMedia-parameter", "Email : " + Email + ", Media : " + Media
                + "MediaType : " + MediaType + ",MediaExt : " + MediaExt);

        MediaAvidance mediainfo = new MediaAvidance();
        mediainfo.EmailId = Email;
        mediainfo.Media = Media;
        mediainfo.MediaExt = MediaExt;
        mediainfo.MediaType = MediaType;

        PropertyInfo pi = new PropertyInfo();
        pi.setName("mediainfo");
        pi.setValue(mediainfo);
        pi.setType(mediainfo.getClass());

        request.addProperty(pi);
/*      request.addProperty("EmailId",Email);
         request.addProperty("Media", Media); 
         request.addProperty("MediaType", MediaType);
         request.addProperty("MediaExtn", MediaExt);
*/       
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                SoapEnvelope.VER11);
        Log.i("SaveMedia","Serialising..");
        new MarshalBase64().register(envelope);
        envelope.dotNet = true;
        envelope.setOutputSoapObject(request);
        HttpTransportSE httpTransport = new HttpTransportSE(
                HelpMeConstant.SOAP_ADDRESS);
        Object response = null;

        try {
            Log.i("SaveMedia","Calling service..");
            httpTransport.call(HelpMeConstant.SOAP_ACTION + "SaveMedia",
                    envelope);
            Log.i("SaveMedia","getting response..");
            response = envelope.getResponse();
        } catch (Exception exception) {
            response = exception.toString();
        }
        Log.i("response", response.toString());
        return response.toString();

and it is sending to a .net web service which is as below :

 [WebMethod]
    public string SaveMedia(MediaAvidance avidanceinfo)
    {
        rs = new ResultSet();
        rs = logictask.SaveMedia(avidanceinfo.EmailId,avidanceinfo.Media,avidanceinfo.MediaType,avidanceinfo.MediaExt);
        return rs.isSuccessfull;
    }

MediaAvidance :

public class MediaAvidance implements KvmSerializable {
    public String EmailId;
    public byte[] Media;
    public String MediaType;
    public String MediaExt;

    public MediaAvidance() {
    }

    public MediaAvidance(String EmailID, byte[] Media, String MediaType,
            String MediaExt) {

        this.EmailId = EmailID;
        this.Media = Media;
        this.MediaType = MediaType;
        this.MediaExt = MediaExt;
    }

    @Override
    public Object getProperty(int arg0) {
        switch (arg0) {
        case GETEMAILID:
            return EmailId;
        case GETMEDIA:
            return Media;
        case GETMEDIATYPE:
            return MediaType;
        case GETMEDIAEXT:
            return MediaExt;
        default:
            return null;
        }
    }

    @Override
    public int getPropertyCount() {
        // TODO Auto-generated method stub
        return 4;
    }

    @SuppressWarnings("rawtypes")
    @Override
    public void getPropertyInfo(int index, Hashtable arg1, PropertyInfo info) {
        switch (index) {
        case 0:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "EmailId";
            break;
        case 1:
            info.type = PropertyInfo.OBJECT_CLASS;
            info.name = "Media";
            break;
        case 2:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "MediaType";
            break;
        case 3:
            info.type = PropertyInfo.STRING_CLASS;
            info.name = "MediaExt";
            break;
        default:
            break;
        }

    }

    @Override
    public void setProperty(int index, Object value) {
        switch (index) {
        case 0:
            EmailId = value.toString();
            break;
        case 1:
            Media = (byte[]) value;
            break;
        case 2:
            MediaType = value.toString();
            break;
        case 3:
            MediaExt = value.toString();
            break;
        default:
            break;
        }
    }
}

At server side MediaAvidance class donot implement KvmSerializable and its method.

I searched for few days and gone through many question in stackoverflow & understood that i am trying to write when the connection is closed and also that it is something related to socket programming. BUT

I don't know how to keep connection alive(probably a solution I think). Please help me.

Thanks, Sourabh

Answer

sourabh gupta picture sourabh gupta · Jan 22, 2014

I finally Managed to get it work. posting this solution hoping it will be usefull for someone like me. You could have more or any of below problem in you code, but I am happy to make these 3 mistakes, and learn from them, that was causing problem in video upload :

  1. I have serialized MediaAvidance in android by implementing KvmSerializable but in order to get it worked your server side MediaAvidance must also be serialized. that I have done by below code which solved my Cannot Serialize Exception I was getting :
   [Serializable]
   public class MediaAvidance

you also need to register your SoapSerializationEnvelopeto MarshalBase64 :

   envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
   new MarshalBase64().register(envelope); 
  1. when you call from android, set exact same name in PropertyInfo as you have in service method parameter(ex : avidanceinfo), this one solved faultstring: 'Server was unable to read request. exception :

    property name defined in android

    pi.setName("avidanceinfo");

    service method :

     [WebMethod]
     public string SaveMedia(MediaAvidance avidanceinfo)

  2. At last your need to add envelope.implicitTypes = true ;
    so that HttpTransportSE will be able to recognise MediaAvidance type at server else you will get Object reference not set to an instance of an object. when using xs:anyType.... Exception.

*Hope this may be helpfull to you. :) *