我想将文本和文件发送到具有本地Wi-Fi网络的应用程序中,我认为对于以下格式的任何通信:
1字节消息模式(文件或文本(+消息长度+消息(文本或文件(
这是我的编写代码:
private void sendFile() throws JSONException {
if (outputStream == null)
return;
InputStream inputFile = null;
try {
outputStream.writeInt(G.FILE_MODE);
outputStream.writeLong(file.length());
inputFile = new FileInputStream(file);
final boolean falg = copyFile(inputFile, outputStream);**
if (falg)
G.logToast("not sent");
else
G.logToast("sent");
}
catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
G.logToast("not sent");
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
outputStream.flush();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte[] buffer = new byte[4096];
try {
while (inputStream.read(buffer) > 0) {
out.write(buffer);
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
try {
inputStream.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return true;
}
这是我的读取代码:
private void readInputStream() {
// TODO Auto-generated method stub
while (true) {
FileOutputStream fos = null;
try {
int mode = dataInputStream.readInt();
G.logW("mode : " + mode);
if (mode != G.FILE_MODE && mode != G.COMMAND_MODE)
continue;
int len = (int) dataInputStream.readLong();
G.logW("len : " + len);
file.delete();
fos = new FileOutputStream(file);
if (mode == G.COMMAND_MODE)
{
byte[] buffer = new byte[len];
dataInputStream.read(buffer, 0, len);
analizeCommand(new String(buffer));
} else if (mode == G.FILE_MODE) {
byte[] buffer = new byte[4096];
int filesize = len; // Send file size in separate msg
int read = 0;
int totalRead = 0;
int remaining = filesize;
while ((read = dataInputStream.read(buffer, 0, Math.min(buffer.length, remaining))) > 0) {
totalRead += read;
remaining -= read;
System.out.println("read " + totalRead + " bytes.");
fos.write(buffer, 0, read);
}
playRecord();
G.logW("new file received ");
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally
{
if (fos != null) {
try {
fos.flush();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
但是当我想分析另一台设备上的消息时,我发现它显示了错误的值
这是我登录的目标设备:
01-25 10:32:36.730 E/SMD ( 129): DCD ON
01-25 10:32:36.970 E/Watchdog( 490): !@Sync 653
01-25 10:32:39.720 W/tag ( 1917): mode : 2
01-25 10:32:39.730 E/SMD ( 129): DCD ON
01-25 10:32:39.730 W/tag ( 1917): len : 35840
01-25 10:32:39.750 W/PowerManagerService( 490): Timer 0x3->0x3|0x0
01-25 10:32:41.500 W/tag ( 1917): new file received
01-25 10:32:41.500 W/tag ( 1917): mode : 8323227
01-25 10:32:41.500 W/tag ( 1917): mode : 13828289
01-25 10:32:41.500 W/tag ( 1917): mode : 14483649
01-25 10:32:41.510 W/tag ( 1917): mode : 10813557
01-25 10:32:41.510 W/tag ( 1917): mode : 4653117
01-25 10:32:41.510 W/tag ( 1917): mode : 3473461
01-25 10:32:41.510 W/tag ( 1917): mode : 3473433
01-25 10:32:41.520 W/tag ( 1917): mode : 1638425
01-25 10:32:41.520 W/tag ( 1917): mode : 1638425
01-25 10:32:41.520 W/tag ( 1917): mode : 1638425
01-25 10:32:41.520 W/tag ( 1917): mode : 65516
01-25 10:32:41.520 W/tag ( 1917): mode : -3735638
01-25 10:32:41.530 W/tag ( 1917): mode : -9240708
01-25 10:32:41.530 W/tag ( 1917): mode : -7405692
01-25 10:32:41.530 W/tag ( 1917): mode : -2424890
01-25 10:32:41.530 W/tag ( 1917): mode : -1900554
01-25 10:32:41.530 W/tag ( 1917): mode : -3080258
01-25 10:32:41.530 W/tag ( 1917): mode : -4259954
01-25 10:32:41.530 W/tag ( 1917): mode : -8061070
01-25 10:32:41.540 W/tag ( 1917): mode : -8585330
01-25 10:32:41.540 W/tag ( 1917): mode : -8061052
01-25 10:32:41.540 W/tag ( 1917): mode : -8061080
01-25 10:32:41.540 W/tag ( 1917): mode : -10420384
01-25 10:32:41.540 W/tag ( 1917): mode : -10420384
为什么会这样?
套接字从dataInputStream读取错误数据
不。你发错了。
-
经典复制循环错误。
while (inputStream.read(buffer) > 0) { out.write(buffer);
那应该是
int count; while ((count = inputStream.read(buffer)) > 0) { out.write(buffer, 0, count);
目前,您在流末尾写入垃圾,并且比向对等方通告的数据多,因此对等方与应用程序协议不同步。
-
命令读取问题:
dataInputStream.read(buffer, 0, len);
这是您阅读命令的位置。它应该是:
dataInputStream.readFully(buffer, 0, len);
-
file.delete();
之前fos = new FileOutputStream(file);
是多余的。 -
您将长度作为
long
发送,然后将其向下转换为int
,并对剩余计数也使用int
。为什么?这意味着你不能发送超过 2GB,这也意味着如果你这样做,你的代码将回到同样的 bozo 模式。您似乎从中复制了此代码的我的答案使用long
.为什么要改变它?
while (inputStream.read(buffer) > 0) {
out.write(buffer);
}
应该是:
int len = 0;
while ((len = inputStream.read(buffer)) >= 0) {
// if len equals 0, you should read continue.
if(len > 0)
{
out.write(buffer,0,len);
}
}