java.net.SocketException: sendto failed: EPIPE (Broken pipe)在发送byte[]时发生了错误。

3

我正在尝试上传通过Android手机录制的视频。但是当将视频作为byte[]发送到服务器时,出现以下错误:

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

以下是我试图上传视频的步骤:
        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();

并且它正在发送到一个 .net web 服务,如下所示:

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

媒体存储:

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;
        }
    }
}

在服务器端,MediaAvidance类没有实现KvmSerializable及其方法。

我搜索了几天,在stackoverflow上看了很多问题,并了解到我正在尝试在连接关闭时编写代码,这与套接字编程有关。但是,我不知道如何保持连接活动(可能是一个解决方案)。请帮助我。

谢谢, Sourabh


你能提供更多来自服务器错误跟踪的行吗?并且你能在这里粘贴MediaAvidance类吗? - kingAm
已添加了MediaAvidance类代码。我在异常中没有得到任何堆栈跟踪。那就是我拥有的所有异常信息。 - sourabh gupta
在您的客户端代码中,您将该视频作为字节数组,然后传递到您的SOAP请求中。由于字节数组太大,可能会在上传完成之前关闭服务器或客户端连接。也许保持此连接活动状态几分钟,直到文件上传完成。您可以搜索一下。也许,仅在客户端实现无法解决您的问题。如果您对服务器有控制权,则首先尝试上传几个字节的图片进行测试,如果成功上传,则我们可以确认您的确切问题。 - kingAm
当我尝试使用18kb的图像进行相同的过程时,我得到了不同的错误:01-20 17:35:40.579: E/SaveDocument-response(13412): SoapFault - faultcode: 'soap:Server' faultstring: 'Server was unable to process request. ---> Method HelpMe.SaveMedia can not be reflected. ---> The XML element 'SaveMedia' from namespace 'http://tempuri.org/' references a method and a type. Change the method's message name using WebMethodAttribute or change the type's root element using the XmlRootAttribute.' faultactor: 'null' detail: org.kxml2.kdom.Node@41df97b0 - sourabh gupta
我现在得到了这个: '01-20 18:43:05.639: E/SaveMedia(16211): SoapFault - faultcode: 'soap:Server' faultstring: '服务器无法处理请求。--->对象引用未设置为对象的实例。' faultactor: 'null' detail: org.kxml2.kdom.Node@41dfc560 01-20 18:43:05.639: E/SaveMedia(16211): at org.ksoap2.serialization.SoapSerializationEnvelope.parseBody(SoapSerializationEnvelope.java:136) 01-20 18:43:05.639: E/SaveMedia(16211): at org.ksoap2.SoapEnvelope.parse(SoapEnvelope.java:137)'在' httpTransport.call '行处 - sourabh gupta
你现在没有在请求中传递某个值。请用你问题中已有的代码替换它。 - kingAm
1个回答

0

我终于设法使它工作了。发布此解决方案,希望对像我一样的某个人有所帮助。您的代码可能会出现更多或任何以下问题,但我很高兴犯了这三个错误,并从中学习,这是导致视频上传问题的原因:

  1. 我通过实现KvmSerializable在Android中对MediaAvidance进行了序列化,但要使其工作,您的服务器端MediaAvidance也必须进行序列化。我通过下面的代码完成了这项工作,解决了我遇到的Cannot Serialize异常:
   [Serializable]
   public class MediaAvidance

您还需要将您的SoapSerializationEnvelope注册到MarshalBase64中:

   envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
   new MarshalBase64().register(envelope); 
  1. 当您从Android调用时,请在PropertyInfo中设置与服务方法参数完全相同的名称(例如:avidanceinfo),这可以解决faultstring: 'Server was unable to read request.异常:

    在Android中定义的属性名称

    pi.setName("avidanceinfo");

    服务方法:

    [WebMethod]
    public string SaveMedia(MediaAvidance avidanceinfo)

  2. 最后,您需要添加 envelope.implicitTypes = true;
    这样HttpTransportSE将能够识别服务器上的MediaAvidance类型,否则您将收到Object reference not set to an instance of an object. when using xs:anyType....异常。

*希望这对您有所帮助。 :)*


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接