首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

android socket 发送大图片,数据丢掉.求解决方案。

2013-01-23 
android socket 发送大图片,数据丢失...求解决方案。。现在是终端之间发送图片,类似微信之间发送图片那样,客

android socket 发送大图片,数据丢失...求解决方案。。
现在是终端之间发送图片,类似微信之间发送图片那样,客户端把图片转化为字节流发给服务器上,然后服务器再找到要发送的人,把数据发给另外终端设备。现在在局域网两台模拟器上发送大图片,发送接收都没问题,部署到外网服务器上,服务器接收代码:   int length = 0;
int totalNum = 0;
byte[] buffer = new byte[1024];
while ((length = dis.readInt()) != 0) {
length = dis.read(buffer, 0, length);
                                        System.out.println("length :-------->" +                                                      length);

totalNum += length;
out.writeInt(length);
out.write(buffer, 0, length);
out.flush();
}
System.out.println("totalNum:-------->" + totalNum);
out.writeInt(0);
out.flush();
Debug.info("totalNum::::" + totalNum);
initService.getEnterpriseMsgService().save(msg);
每次接收1024个字节,有时候到System.out.println("length :-------->" + length);----直接为null,模拟器上每次发送和接收的数据是一致的,发送大图片就没这个问题。各位大神,求解决方案,是代码的问题,还是服务器的问题(公司的一台PC机,很卡的那种)。。。


[解决办法]
应该是代码的问题,理论上讲用socket的TCP不存在数椐丢失的问题.通常有这样的误区,发送方1k1k发,接收方1k1k的收,想当然就是1k一个包,是按包发送接收; 当网络捅挤的时,接收方一次响应收到的不一定是1k;可能是800;另外200在下一次响应中;所以应用流的概念来编程,而不是用包的概念;
[解决办法]
自己直接用socket传需要很好的底层设计,你不如直接用http协议这样的上层传简单些
[解决办法]

引用:
现在是终端之间发送图片,类似微信之间发送图片那样,客户端把图片转化为字节流发给服务器上,然后服务器再找到要发送的人,把数据发给另外终端设备。现在在局域网两台模拟器上发送大图片,发送接收都没问题,部署到外网服务器上,服务器接收代码:   int length = 0;
int totalNum = 0;
byte[] buffer = new byte[1024];
……


我知道原因,我也遇到过,,,,

1024  太大了,如果图片小于1024 你就直接读到后面的了。。。。

size是文件的大小。。。。




byte[] buffer;
if (size > 1024)
buffer = new byte[1024];
else
buffer = new byte[size];

[解决办法]
还是老毛病;length = dis.read(buffer, 0, length); 这时想读和实际读取的数椐不一定一致;你换个参数名打印出来试试.
另外,你中间插入的int几乎没有作用,且可能读到buffer里面去,建议不要。
发送端先把总长传过去,然后一直送
totalNum = 文件长;
dos.writeInt(totalNum);
while (totalNum > 0) {
    length = ddis.read(buffer);
    dos.write(buffer, 0, length);
    dos.flush();
    totalNum -= length;
}
接收端确定总长后,一直读,直到整个文件传送结束。
totalNum = dis.readInt();
while (totalNum > 0) {
    length = dis.read(buffer, 0, 1024);
    if(length > 0)
    {
        ddos.write(buffer, 0, length);
        ddos.flush();


        totalNum -= length;
    }
}


[解决办法]
代码写得很奇怪,while ((length = dis.readInt()) != 0) 这句导致很多不确定性。
因为你不一定刚好来的数据就是你的头,可能刚好起点位置是在图片数据中某段4个字节为0的地方,那么这时候就不会正常执行下去。

如果你希望1K,1K地将数据从一端转发到另一端,完全不需要这么写。可以在服务器端,通过标识变量来记录就可以了。比如 
int blockLength=0;
int buffLength = 1024;
int receivedLength =0;
byte[] buffer = new byte[buffLength];
int startPos = 0;
while((length = dis.read(buffer, startPos, buffLength-startPos)) > 0){
  if(startPos+length == buffLength){
     // a block is full, send it to client
     startPos = 0; // reset startPos
  }
  else{
     startPos += length;
  }
}

热点排行