【问题标题】:java.net.SocketException: sendto failed: EPIPE (Broken pipe) while sending byte[]java.net.SocketException:sendto 失败:发送字节时 EPIPE(断管)[]
【发布时间】:2014-02-09 07:21:48
【问题描述】:

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

  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 网络服务,如下所示:

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

在服务器端 MediaAvidance 类不实现KvmSerializable 及其方法。

我搜索了几天并在 stackoverflow 中解决了许多问题,并了解到我正在尝试在连接关闭时编写,并且它与套接字编程有关。但是

我不知道如何保持连接(我认为可能是一个解决方案)。 请帮我。

谢谢, 苏拉布

【问题讨论】:

  • 您能否在此处从服务器错误跟踪中提供更多行。您能否在此处粘贴 MediaAvidance 类。
  • MediaAvidance 类代码已添加。我没有任何堆栈跟踪异常。这就是我唯一的例外。
  • 我认为,在您的客户端代码中,您将该视频作为字节数组传递,然后将其传递给您的肥皂请求。很可能是由于字节数组的大小,您的服务器或客户端连接在上传完成之前已关闭。可能会将此连接保持几分钟您的文件上传。您可以搜索它。可能是,您不会通过仅在客户端实现它来解决您的问题。如果您可以控制服务器,那么为了测试首先尝试上传一张有几个字节的图片,如果它成功上传,那么我们可以在这里确认您的确切问题.
  • 当我尝试对 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
  • 我现在得到了这个:'01-20 18:43:05.639: E/SaveMedia(16211): SoapFault - faultcode: 'soap:Server' faultstring: '服务器无法处理请求。 ---> 对象引用未设置为对象的实例。 faultactor:'null' 详细信息:org.kxml2.kdom.Node@41dfc560 01-20 18:43:05.639:E/SaveMedia(16211):在 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)' at line 'httpTransport.call' '\n' if you can help Now

标签: android web-services socketexception


【解决方案1】:

我终于设法让它工作了。发布此解决方案,希望它对像我这样的人有用。您的代码中可能有更多或任何以下问题,但我很高兴犯这 3 个错误,并从中吸取教训,这导致了视频上传问题:

  1. 我已经通过实现KvmSerializable 在android 中序列化了MediaAvidance,但为了使其正常工作,您的服务器端MediaAvidance 也必须进行序列化。我通过下面的代码完成了我得到的Cannot Serialize 异常:
 [可序列化]
   公共类MediaAvidance

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

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

    在android中定义的属性名

    pi.setName("avidanceinfo");

    服务方式:

    [网络方法] 公共字符串 SaveMedia(MediaAvidance avidanceinfo)
  2. 最后你需要添加 envelope.implicitTypes = true ;
    这样HttpTransportSE 将能够在服务器上识别MediaAvidance 类型,否则您将获得Object reference not set to an instance of an object. when using xs:anyType.... 异常。

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

【讨论】:

    猜你喜欢
    • 2013-01-26
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 2014-11-24
    • 2015-05-24
    • 2010-12-26
    • 1970-01-01
    相关资源
    最近更新 更多