我声明我是论坛的新人,因此我希望能够很好地提出问题以获得答案。我编写的代码适用于所有Android设备,除了那些带有marshmallow操作系统的设备(支持我的最低版本)。在模拟器和物理设备上使用noughat和oreo都没问题。
我有这个错误java.net.SocketException:sendto failed:EPIPE(Broken pipe)我尝试了在论坛上找到的任何可能的解决方案,但没有任何效果。我真的希望有人可以帮助我,因为我很长时间以来一直坚持这个错误。
当我尝试使用multipart / form-data将一个字节形式的文件发送到我在nodejs中写入的服务器时,会发生错误。这是我的android类SendFile,我尝试发送文件:
public void addParam(String key, String param) {
if (parameter.length() > 0) {
parameter += "&";
} else {
parameter += "?";
}
parameter += key + "=" + param;
}
private String getParam() {
return parameter;
}
@Override
protected String doInBackground(String... params) {
String fileUri = params[1];
String attachmentName = params[2];
String crlf = "\r\n";
String twoHyphens = "--";
String boundary = "+++++";
String response = "";
try {
addAuthentication();
String urlString = AppConfiguration.URLFORSERVER + params[0];
if (parameter.length() > 0) {
urlString += getParam();
}
URL url = new URL(urlString);
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setDoInput(true);
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("Connection", "Keep-Alive");
httpUrlConnection.setRequestProperty("Cache-Control", "no-cache");
httpUrlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
httpUrlConnection.connect();
DataOutputStream dos = new DataOutputStream(httpUrlConnection.getOutputStream());
dos.writeBytes(twoHyphens + boundary + crlf);
dos.writeBytes("Content-Disposition: form-data; name=\"" + attachmentName + "\";");
dos.writeBytes(" filename=\"" + fileUri + '"' + crlf);
dos.writeBytes(crlf);
// Read from InputStream and write to OutputStream
InputStream fileInputStream = activity.getContentResolver().openInputStream(Uri.parse(fileUri));
byte[] outputBytes = readBytes(fileInputStream);
OutputStream os = httpUrlConnection.getOutputStream();
os.write(outputBytes);
dos.writeBytes(crlf);
dos.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
dos.flush();
os.flush();
os.close();
// Read the input stream into a String
InputStream inputStream = httpUrlConnection.getInputStream();
StringBuilder stringBuffer = new StringBuilder();
if (inputStream != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
stringBuffer.append(line);
}
if (stringBuffer.length() != 0) {
response = stringBuffer.toString();
}
}
httpUrlConnection.disconnect();
} catch (IOException e) {
response = null;
e.printStackTrace();
}
return response;
}
private void addAuthentication() {
Utility utilitySharedPreferences = new Utility(activity);
User user = utilitySharedPreferences.isLoggedIn();
if (user != null) {
addParam("authid_user", user.get_id());
addParam("authmobile_token", user.getMobileToken());
}
}
错误是:
W/System.err: java.net.SocketException: sendto failed: EPIPE (Broken pipe)
W/System.err: at libcore.io.IoBridge.maybeThrowAfterSendto(IoBridge.java:549)
W/System.err: at libcore.io.IoBridge.sendto(IoBridge.java:518)
at java.net.PlainSocketImpl.write(PlainSocketImpl.java:500)
at java.net.PlainSocketImpl.access$100(PlainSocketImpl.java:37)
at java.net.PlainSocketImpl$PlainSocketOutputStream.write(PlainSocketImpl.java:266)
at com.android.okhttp.okio.Okio$1.write(Okio.java:76)
at com.android.okhttp.okio.AsyncTimeout$1.write(AsyncTimeout.java:155)
at com.android.okhttp.okio.RealBufferedSink.emitCompleteSegments(RealBufferedSink.java:176)
at com.android.okhttp.okio.RealBufferedSink.write(RealBufferedSink.java:46)
at com.android.okhttp.internal.http.RetryableSink.writeToSocket(RetryableSink.java:78)
at com.android.okhttp.internal.http.HttpConnection.writeRequestBody(HttpConnection.java:240)
at com.android.okhttp.internal.http.HttpTransport.writeRequestBody(HttpTransport.java:56)
at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:784)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:439)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
at com.copyshop.core.copyshopproject.utility.SendFile.doInBackground(SendFile.java:115)
at com.copyshop.core.copyshopproject.utility.SendFile.doInBackground(SendFile.java:41)
at android.os.AsyncTask$2.call(AsyncTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:246)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:833)
Caused by: android.system.ErrnoException: sendto failed: EPIPE (Broken pipe)
W/System.err: at libcore.io.Posix.sendtoBytes(Native Method)
at libcore.io.Posix.sendto(Posix.java:211) at
libcore.io.BlockGuardOs.sendto(BlockGuardOs.java:278) at
libcore.io.IoBridge.sendto(IoBridge.java:516)
... 22 more
它出现在
行 InputStream inputStream = httpUrlConnection.getInputStream();
据我所知,出现此错误是因为服务器以意外方式关闭了连接。 这是我的服务器代码。我使用multer将文件保存在服务器上的本地文件夹中:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, pdfPath);
},
filename: function (req, file, cb) {
cb(null, randomstring.generate(8) + '-' + Date.now() + '-' + req.query.filename);
}
});
var upload = multer({storage: storage});
module.exports = function (app) {
app.post('/api/loadOrder', utility.autMobile, upload.single('file'), function(req, res) {
pdfjsLib.getDocument(pdfPath + req.file.filename).then(function (doc) {
var numPages = doc.numPages;
var date = new Date(req.query.deliveryDate).getTime();
var todayDate = new Date(req.query.todayDate).getTime();
var newOrder = new Order({
user : req.user._id,
uploadDate : new Date().getTime(),
deliveryDate : date,
file : '/api/downloadFile?filePath=pdf/' + req.file.filename,
filename : req.query.filename,
pageNumber : numPages,
numCopies : Number(req.query.numCopies),
color : (req.query.color === "true"),
frontBack : (req.query.frontBack === "true"),
binding : (req.query.binding === "true"),
contact : req.query.contact,
notes : req.query.notes
});
newOrder.save(function(err, order) {
if (err) {
res.status(401).send();
} else {
res.send('Order saved');
}
});
}).catch(function (err) {
console.log(err);
res.status(404).send();
});
});
};
非常感谢。
UPDATE1: 我改变了这个,谢谢@greenapps
DataOutputStream dos = new
DataOutputStream(httpUrlConnection.getOutputStream());
dos.writeBytes(twoHyphens + boundary + crlf);
dos.writeBytes("Content-Disposition: form-data; name=\"" + attachmentName + "\";");
dos.writeBytes(" filename=\"" + fileUri + '"' + crlf);
dos.writeBytes(crlf);
// Read from InputStream and write to OutputStream
InputStream fileInputStream = activity.getContentResolver().openInputStream(Uri.parse(fileUri));
byte[] outputBytes = readBytes(fileInputStream);
dos.write(outputBytes);
dos.writeBytes(crlf);
dos.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
dos.flush();
UPDATE2: 谢谢@greenapps但不幸的是问题仍然存在
@Override
protected String doInBackground(String... params) {
String fileUri = params[1];
String attachmentName = params[2];
String fileName = params[3];
String crlf = "\r\n";
String twoHyphens = "--";
String boundary = "+++++";
String response = "";
try {
addAuthentication();
String urlString = AppConfiguration.URLFORSERVER + params[0];
if (parameter.length() > 0) {
urlString += getParam();
}
URL url = new URL(urlString);
HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setDoInput(true);
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.setRequestProperty("Connection", "Keep-Alive");
httpUrlConnection.setRequestProperty("Cache-Control", "no-cache");
httpUrlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
DataOutputStream dos = new
DataOutputStream(httpUrlConnection.getOutputStream());
dos.writeBytes(twoHyphens + boundary + crlf);
dos.writeBytes("Content-Disposition: form-data; name=\"" +
attachmentName + "\";");
dos.writeBytes(" filename=\"" + fileName + '"' + crlf);
dos.writeBytes(crlf);
// Read from InputStream and write to OutputStream
InputStream fileInputStream = activity.getContentResolver().openInputStream(Uri.parse(fileUri));
byte[] outputBytes = readBytes(fileInputStream);
dos.write(outputBytes);
dos.writeBytes(crlf);
dos.writeBytes(twoHyphens + boundary + twoHyphens + crlf);
dos.flush();
Lod.d(httpUrlConnection.getResponseCode());
// Read the input stream into a String
InputStream inputStream = httpUrlConnection.getInputStream();
StringBuilder stringBuffer = new StringBuilder();
if (inputStream != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
stringBuffer.append(line);
}
if (stringBuffer.length() != 0) {
response = stringBuffer.toString();
}
}
httpUrlConnection.disconnect();
} catch (IOException e) {
response = null;
e.printStackTrace();
}
return response;
}