最近在写一个客户端,与服务器端用socket通讯,是个点菜的,需要从服务器端获取菜单信息,数据量有点大,差不多有1K左右,粘点代码如下
while (!mIsStop) {
try {
Log.i("mSocket 201 at TCPListener", mSocket.toString());
buf = new BufferedInputStream(mSocket.getInputStream());
byte[] bufArray = new byte[Global.SIZE_OF_PACKET_HEAD];
int temp = 100;
do
{
temp = buf.read(bufArray, 0, Global.SIZE_OF_PACKET_HEAD);
}
while(temp == 0);
Log.i("TCPListener ", "*****203");
if (true) {
byte commandType = bufArray[4];
command = (short) commandType;
byte backFlag = bufArray[5];
flag = (short) backFlag;
Log.e("command", command + "");
Log.e("success 0,fail 1", flag + "");
dataLength = Global.ntohs(bufArray, 6);
Log.i("dataLength: TCPListenerThread", dataLength + "");
}
} catch (Exception e) {
e.printStackTrace();
stopListen();
if(null != mDlgTable)
{
if(!mIsHurry)
{
mDlgTable.getDelay();
mIsHurry = false;
}
}
// return;
}
           if(Global.CmdType.cmdGetDishInfo.ordinal() == command) 
{
// if (dataLength == 0) {
// mDlgTable.setDishInfo(dish);
// dish = null;
// dish = new ArrayList<DishInfo>();
// break;
// }
int dishNumber;
dishNumber = dataLength / dishSize;
Log.i("dishNumber", "" + dishNumber);
byte[] bufArray = null;
for (int i = 0; i < dishNumber; i++) {
try {
bufArray = new byte[dishSize];
int temp = 100;
do
{
temp = buf.read(bufArray, 0, dishSize);
}
while(temp == 0);
Global.DishInfo dishInfo = new Global.DishInfo(bufArray,
0);
if(dishInfo.name.length() >= 1)
{
dish.add(dishInfo);
}
} catch (Exception e2) {
Log.e("Dish Info catch Exception",
"TCPListener while command =      Global.CmdType.cmdGetDishInfo");
e2.printStackTrace();
}
}
}

dataLength是除了包头后面的数据长度,即从服务器发过来的数据长度,今天在wifi环境下测试,有一次获取到的部分菜有问题,解析是没有问题的,大部分情况下也是正常的,前几天在3G环境下出了不少次这样的问题,大家看看我在读取数据那是不是有问题,特别是网络堵塞的时候容易出问题

解决方案 »

  1.   

    没有报错,就是
    do
    {
    temp = buf.read(bufArray, 0, dishSize);
    }
    while(temp == 0);
    Global.DishInfo dishInfo = new Global.DishInfo(bufArray,
    0);
    这几行接收有问题,服务器发来的一个数据包,该数据包前面的内容能够正常的接收解析,后面的数据可能是没接收完或者有问题,解析的不对
      

  2.   

    do
    {
    temp = buf.read(bufArray, 0, dishSize);
    }
    while(temp != -1);
    Global.DishInfo dishInfo = new Global.DishInfo(bufArray,
    0);
    读取到流的末尾,会返回-1,所以你应该使用-1来做判断,
    我不知道为什么要使用while(temp==0)来判断啊,这样实际读取的字节个数不为0,那么将会跳出循环,这样肯定会有东西读取不到的
      

  3.   

    do
    {
    temp = buf.read(bufArray, 0, dishSize);
    }
    while(temp == 0);并不是说你指定读dishSize,就一定会读dishSize长的字节。dishSize只是告诉io,你这个缓冲区的长度是这么长。真正读多少是来自返回值的,也就是temp
    所以有可能你没有读到dishSize长的字节流,就返回了,并且temp非0
    另外一个,tcp在网络切换的时候,比如3g/wifi切换,需要处理一些问题,这个我就不懂了,是听人说的,具体也不了解
    最后,建议你这种应用,还是用http好,http最适合这种环境,而且用文本协议而不是二进制协议,也有利于移植,跨平台。服务器也好做,简单的搭个rest,好调试,高吞吐和高可用 用tcp的话,看lz你写的代码,要是服务器也是lz你做的,我估计最高不过1000
      

  4.   

    我是新手,服务器是另一个同事做的,他才是真正的高手,C++写的,只能用socket写啊,我说了不算,好多东西也都不懂,这是我第一个项目,也没什么经验,谢谢六楼,还有五楼