通过alljoyn传输文件










  通过alljoyn传输文件(1)  2012-12-11 14:41:42

分类: 嵌入式

    Alljoyn是高通开发的一个开源的p2p通信框架,支持wifi/蓝牙和wifi-direct。目前已经有了很多基于这个框架开发的联机游戏。
    在Alljoyn的sdk里有很多例子,其中有一个通过raw session发送信息的,对这个例子略加修改就可以实现两个手机之间文件的传输。
     在client端,其发送的信息是通过一个FileOutputStream将要发送的信息写入到一个中间文件来发送到对方的。所以我们只要将要发送的文件通过流的形式输入到这个FileOutputStream中就可以了。

点击(此处)折叠或打开

  1. if (mStreamUp == true) {
  2.                     String string = (String) msg.obj + "\n";
  3.                     try {
  4.                         // logInfo(String.format("Writing %s to output stream",

  5.                         // string));

  6.                         // mOutputStream.write(string.getBytes());

  7.                         // logInfo(String.format("Flushing stream", string));

  8.                         // mOutputStream.flush();

  9.                         String filepath = "/sdcard/test.txt";
  10.                         File file = new File(filepath);
  11.                         InputStream in =new FileInputStream(file);
  12.                         byte[] buffer = new byte[1024];
  13.                         int read;
  14.                         long total = 0;
  15.                         while ((read = in.read(buffer)) != -1) {
  16.                             mOutputStream.write(buffer, 0, read);
  17.                             total+=read;
  18.                             Log.d("test","total:"+total);
  19.                             if(total>100000){
  20.                                 mOutputStream.flush();
  21.                                 total=0;
  22.                                 //容易出现io exception,所以稍微等待一下。

  23.                                 Thread.sleep(100);
  24.                             }
  25.                         }
  26.                         mOutputStream.flush();
  27.                         Log.d("test","flush");
  28.                         in.close();
  29.                     } catch (IOException ex) {
  30.                         Log.e("test",ex.toString());
  31.                     } catch (InterruptedException e) {
  32.                         // TODO Auto-generated catch block

  33.                         e.printStackTrace();
  34.                     }
  35.                 }
  36.                 break;
  37.             }
     其中前面注释掉的代码是实例程序原来的,下面的就是我修改的,将文件输入到输出流中。需要注意的是如果不加中间的sleep的话就会报IO Exception,这是因为raw使用的是非阻塞式socket发送的,如果发送得过快而网络传输得慢就会产生异常,中断传输。就好像一个大水池,一个水管往里注水,一个水管往外放水,如果注水的速度大于放水的速度的话水池就会溢出。所以在写入的时候稍微睡眠一下,也就是稍微控制一下注入的速度,让底层把内容发出去。
    虽然这样可以在一定程度上减少异常的发生,但是传输的文件如果太大的话还是容易产生异常的,在这种情况下可以使用try catch来捕获这个异常然后休眠一段时间从中断的位置重新传输。
 
    在server端,我们只需要将接受到的流写入到一个新建的文件中就可以了。其中注释掉的也是其原来的程序。

点击(此处)折叠或打开

  1. mReader = new Thread(new Runnable() {
  2.                         public void run() {
  3.                             logInfo("Thread running");
  4.                             Looper.myLooper().prepare(); 
  5.                             StringBuilder stringBuilder = new StringBuilder();
  6.                             try {
  7.                                 while (true) {
  8.                                     int c;
  9.                                     /*
  10.                                      * Wait until a character is available.
  11.                                      */
  12.                                     if (reader.ready() == false) {
  13.                                         Thread.sleep(100);
  14.                                         continue;
  15.                                     }
  16.                                     
  17.                                     /*
  18.                                      * Build a string out of the characters and
  19.                                      * when we see a newline, cook up a toast
  20.                                      * do display them.
  21.                                      */
  22.                                     if(saveFile("/mnt/sdcard/test.txt",is)){
  23.                                         Toast.makeText(Service.this, "save success", Toast.LENGTH_LONG).show();
  24.                                     }else{
  25.                                         Toast.makeText(Service.this, "save faild", Toast.LENGTH_LONG).show();
  26.                                     }
  27. //                     try {

  28. //                         c = reader.read();

  29. //                         logInfo(String.format("Read %d from stream", c));

  30. //                         stringBuilder.append((char)c);

  31. //                         if (c == 10) {

  32. //                             String s = stringBuilder.toString();

  33. //                         logInfo(String.format("Read %s from stream", s));

  34. //              Message toastMsg = mHandler.obtainMessage(MESSAGE_POST_TOAST, s);

  35. //              mHandler.sendMessage(toastMsg);

  36. //          stringBuilder.delete(0, stringBuilder.length() - 1);

  37. //                         }

  38. //                     } catch (IOException ex) {

  39. //                     }

  40.                                 }
  41.                             } catch (Throwable ex) {
  42.                                  logInfo(String.format("Exception reading raw Java stream: %s", ex.toString()));
  43.                             }
  44.                             logInfo("Thread exiting");
  45.                         }
  46.                     }, "reader");
  47.                     mReader.start();
    我们还需要加入一个保存文件的函数:

点击(此处)折叠或打开

  1. private static boolean saveFile(String filePath, InputStream is) {
  2.         boolean saved = false;
  3.         byte[] buffer = new byte[1024];
  4.         FileOutputStream fos = null;
  5.         File file = null;
  6.         try {
  7.             try {
  8.                 file = new File(filePath);
  9.                 fos = new FileOutputStream(file,true);
  10.             } catch (Exception e) {
  11.                 Log.e(TAG,"creat file error");
  12.             }
  13.             int readlen = -1;
  14.             long readCount = 0;
  15.             while (true) {
  16.                 saved = true;
  17.                 try {
  18.                     readlen = is.read(buffer);
  19.                 } catch (IOException e) {
  20.                      Log.e(TAG,"read inputstream error");
  21.                 } finally {
  22.                     if (readlen <= 0) {
  23.                         break;
  24.                     }
  25.                 }
  26.                 readCount += readlen;
  27.                 Log.d("test","FILE length::::::::::::::::::::"+readCount);
  28.                 try {
  29.                     fos.write(buffer, 0, readlen);
  30.                 } catch (IOException e) {
  31.                     Log.e(TAG,"write file error");
  32.                 }
  33.             }
  34.         } finally {
  35.             if (fos != null) {
  36.                 try {
  37.                     fos.close();
  38.                 } catch (IOException e) {
  39.                     Log.e(TAG, e.toString());
  40.                     }
  41.                 }
  42.                 fos = null;
  43.             }
  44.      Log.d("test","saved:"+saved);
  45.         return saved;
  46.     }

     好了,这样在client端的sd卡的根目录中新建一个test.txt文件,当两个手机连接起来后,client端随便发送一个字符串就可以触发传输文件的操作了。

 



 
 
 
 





  通过alljoyn传输文件(2)  2012-12-19 14:39:41

分类: 嵌入式

     上一篇文章介绍了使用alljoyn的raw方式进行文件的传输,其实那种方法不是很实用,并不是一种好的方式,这篇文章介绍一下使用alljoyn的signal方式进行文件的传输。
     在alljoyn的sdk里面有个chat的例子,这个例子就是使用signal传输手机间的聊天信息的。我们所要做的就是将其修改一下来传输我们的文件。
     首先修改ChatInterface.java里面的接口,将参数从string 类型改成byte[]类型,如下所示:

点击(此处)折叠或打开

  1. public void Chat(byte[] str) throws Bu***ception;
     这就表示我们传输的不是字符串而是byte数组了。所以接下来的问题就是将文件内容转换成一系列的byte数组发出去然后接收这些byte数组并重新组成文件就可以了。首先来看发送,发送时在AllJoynService.java的doSendMessages()方法。


点击(此处)折叠或打开

  1. try {
  2.                 if (mJoinedToSelf) {
  3.                     if (mHostChatInterface != null) {
  4.                         // mHostChatInterface.Chat(message);

  5.                     }
  6.                 } else {
  7.                     SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss ");
  8.                     Date curDate = new Date(System.currentTimeMillis());// 获取当前时间

  9.                     String str = formatter.format(curDate);
  10.                     Log.d("test", "start:" + str+"::::");
  11.                     String filepath = "/sdcard/Picture/100ANDRO/MOV_0426.mp4";
  12.                     File file = new File(filepath);
  13.                     InputStream in = null;
  14.                     try {
  15.                         in = new FileInputStream(file);
  16.                     } catch (FileNotFoundException e1) {
  17.                         // TODO Auto-generated catch block

  18.                         e1.printStackTrace();
  19.                     }
  20.                     byte[] buffer = new byte[102400];
  21.                     int read = 0;
  22.                     while ((read = in.read(buffer)) != -1) {
  23.                         mChatInterface.Chat(buffer);
  24.                         buffer = new byte[102400];
  25.                     }
  26.                     in.close();
  27.                     curDate = new Date(System.currentTimeMillis());// 获取当前时间

  28.                     str = formatter.format(curDate);
  29.                     Log.d("test", "end:" + str+"::::");
  30.                 }
  31.             } catch (Bu***ception ex) {
  32.                 mChatApplication.alljoynError(ChatApplication.Module.USE,
  33.                         "Bus exception while sending message: (" + ex + ")");
  34.             } catch (IOException e) {
  35.                 Log.d("test", e.toString());
  36.             }
      在发送的前后加上系统的时间这样就可以测试发送文件花费的时间。接收是在Chat(byte[] string) 方法里面。

点击(此处)折叠或打开

  1. public void Chat(byte[] string) {

  2.         /*
  3.          * See the long comment in doJoinSession() for more explanation of why
  4.          * this is needed.
  5.          * 
  6.          * The only time we allow a signal from the hosted session ID to pass
  7.          * through is if we are in mJoinedToSelf state. If the source of the
  8.          * signal is us, we also filter out the signal since we are going to
  9.          * locally echo the signal.
  10.          */
  11.         String uniqueName = mBus.getUniqueName();
  12.         MessageContext ctx = mBus.getMessageContext();
  13.         Log.i(TAG, "Chat(): use sessionId is " + mUseSessionId);
  14.         Log.i(TAG, "Chat(): message sessionId is " + ctx.sessionId);

  15.         /*
  16.          * Always drop our own signals which may be echoed back from the system.
  17.          */
  18.         if (ctx.sender.equals(uniqueName)) {
  19.             Log.i(TAG, "Chat(): dropped our own signal received on session "
  20.                     + ctx.sessionId);
  21.             return;
  22.         }

  23.         /*
  24.          * Drop signals on the hosted session unless we are joined-to-self.
  25.          */
  26.         if (mJoinedToSelf == false && ctx.sessionId == mHostSessionId) {
  27.             Log.i(TAG, "Chat(): dropped signal received on hosted session "
  28.                     + ctx.sessionId + " when not joined-to-self");
  29.             return;
  30.         }

  31.         /*
  32.          * To keep the application simple, we didn't force users to choose a
  33.          * nickname. We want to identify the message source somehow, so we just
  34.          * use the unique name of the sender's bus attachment.
  35.          */
  36.         String nickname = ctx.sender;
  37.         nickname = nickname
  38.                 .substring(nickname.length() - 10, nickname.length());

  39.         // Log.i(TAG, "Chat(): signal " + string + " received from nickname " +

  40.         // nickname);

  41. //        mChatApplication.newRemoteUserMessage(nickname, "get message");

  42.         try {
  43.             try {
  44.                 if (file == null) {
  45.                     file = new File("/mnt/sdcard/abc.mp4");
  46.                 }
  47.                 fos = new FileOutputStream(file, true);
  48.             } catch (Exception e) {
  49.                 Log.e(TAG, "creat file error");
  50.             }
  51.             try {
  52.                 fos.write(string, 0, string.length);
  53.             } catch (IOException e) {
  54.                 Log.e(TAG, "write file error");
  55.             }

  56.         } finally {
  57.             if (fos != null) {
  58.                 try {
  59.                     fos.close();
  60.                 } catch (IOException e) {
  61.                     Log.e(TAG, e.toString());
  62.                 }
  63.             }
  64.             fos = null;
  65.         }
  66.     }
       这样就可以进行文件的传输了,测试表明这个方法比上个方法更快更稳定了。
 
















  通过alljoyn传输文件(1)  2012-12-11 14:41:42

分类: 嵌入式

    Alljoyn是高通开发的一个开源的p2p通信框架,支持wifi/蓝牙和wifi-direct。目前已经有了很多基于这个框架开发的联机游戏。
    在Alljoyn的sdk里有很多例子,其中有一个通过raw session发送信息的,对这个例子略加修改就可以实现两个手机之间文件的传输。
     在client端,其发送的信息是通过一个FileOutputStream将要发送的信息写入到一个中间文件来发送到对方的。所以我们只要将要发送的文件通过流的形式输入到这个FileOutputStream中就可以了。

点击(此处)折叠或打开

  1. if (mStreamUp == true) {
  2.                     String string = (String) msg.obj + "\n";
  3.                     try {
  4.                         // logInfo(String.format("Writing %s to output stream",

  5.                         // string));

  6.                         // mOutputStream.write(string.getBytes());

  7.                         // logInfo(String.format("Flushing stream", string));

  8.                         // mOutputStream.flush();

  9.                         String filepath = "/sdcard/test.txt";
  10.                         File file = new File(filepath);
  11.                         InputStream in =new FileInputStream(file);
  12.                         byte[] buffer = new byte[1024];
  13.                         int read;
  14.                         long total = 0;
  15.                         while ((read = in.read(buffer)) != -1) {
  16.                             mOutputStream.write(buffer, 0, read);
  17.                             total+=read;
  18.                             Log.d("test","total:"+total);
  19.                             if(total>100000){
  20.                                 mOutputStream.flush();
  21.                                 total=0;
  22.                                 //容易出现io exception,所以稍微等待一下。

  23.                                 Thread.sleep(100);
  24.                             }
  25.                         }
  26.                         mOutputStream.flush();
  27.                         Log.d("test","flush");
  28.                         in.close();
  29.                     } catch (IOException ex) {
  30.                         Log.e("test",ex.toString());
  31.                     } catch (InterruptedException e) {
  32.                         // TODO Auto-generated catch block

  33.                         e.printStackTrace();
  34.                     }
  35.                 }
  36.                 break;
  37.             }
     其中前面注释掉的代码是实例程序原来的,下面的就是我修改的,将文件输入到输出流中。需要注意的是如果不加中间的sleep的话就会报IO Exception,这是因为raw使用的是非阻塞式socket发送的,如果发送得过快而网络传输得慢就会产生异常,中断传输。就好像一个大水池,一个水管往里注水,一个水管往外放水,如果注水的速度大于放水的速度的话水池就会溢出。所以在写入的时候稍微睡眠一下,也就是稍微控制一下注入的速度,让底层把内容发出去。
    虽然这样可以在一定程度上减少异常的发生,但是传输的文件如果太大的话还是容易产生异常的,在这种情况下可以使用try catch来捕获这个异常然后休眠一段时间从中断的位置重新传输。
 
    在server端,我们只需要将接受到的流写入到一个新建的文件中就可以了。其中注释掉的也是其原来的程序。

点击(此处)折叠或打开

  1. mReader = new Thread(new Runnable() {
  2.                         public void run() {
  3.                             logInfo("Thread running");
  4.                             Looper.myLooper().prepare(); 
  5.                             StringBuilder stringBuilder = new StringBuilder();
  6.                             try {
  7.                                 while (true) {
  8.                                     int c;
  9.                                     /*
  10.                                      * Wait until a character is available.
  11.                                      */
  12.                                     if (reader.ready() == false) {
  13.                                         Thread.sleep(100);
  14.                                         continue;
  15.                                     }
  16.                                     
  17.                                     /*
  18.                                      * Build a string out of the characters and
  19.                                      * when we see a newline, cook up a toast
  20.                                      * do display them.
  21.                                      */
  22.                                     if(saveFile("/mnt/sdcard/test.txt",is)){
  23.                                         Toast.makeText(Service.this, "save success", Toast.LENGTH_LONG).show();
  24.                                     }else{
  25.                                         Toast.makeText(Service.this, "save faild", Toast.LENGTH_LONG).show();
  26.                                     }
  27. //                     try {

  28. //                         c = reader.read();

  29. //                         logInfo(String.format("Read %d from stream", c));

  30. //                         stringBuilder.append((char)c);

  31. //                         if (c == 10) {

  32. //                             String s = stringBuilder.toString();

  33. //                         logInfo(String.format("Read %s from stream", s));

  34. //              Message toastMsg = mHandler.obtainMessage(MESSAGE_POST_TOAST, s);

  35. //              mHandler.sendMessage(toastMsg);

  36. //          stringBuilder.delete(0, stringBuilder.length() - 1);

  37. //                         }

  38. //                     } catch (IOException ex) {

  39. //                     }

  40.                                 }
  41.                             } catch (Throwable ex) {
  42.                                  logInfo(String.format("Exception reading raw Java stream: %s", ex.toString()));
  43.                             }
  44.                             logInfo("Thread exiting");
  45.                         }
  46.                     }, "reader");
  47.                     mReader.start();
    我们还需要加入一个保存文件的函数:

点击(此处)折叠或打开

  1. private static boolean saveFile(String filePath, InputStream is) {
  2.         boolean saved = false;
  3.         byte[] buffer = new byte[1024];
  4.         FileOutputStream fos = null;
  5.         File file = null;
  6.         try {
  7.             try {
  8.                 file = new File(filePath);
  9.                 fos = new FileOutputStream(file,true);
  10.             } catch (Exception e) {
  11.                 Log.e(TAG,"creat file error");
  12.             }
  13.             int readlen = -1;
  14.             long readCount = 0;
  15.             while (true) {
  16.                 saved = true;
  17.                 try {
  18.                     readlen = is.read(buffer);
  19.                 } catch (IOException e) {
  20.                      Log.e(TAG,"read inputstream error");
  21.                 } finally {
  22.                     if (readlen <= 0) {
  23.                         break;
  24.                     }
  25.                 }
  26.                 readCount += readlen;
  27.                 Log.d("test","FILE length::::::::::::::::::::"+readCount);
  28.                 try {
  29.                     fos.write(buffer, 0, readlen);
  30.                 } catch (IOException e) {
  31.                     Log.e(TAG,"write file error");
  32.                 }
  33.             }
  34.         } finally {
  35.             if (fos != null) {
  36.                 try {
  37.                     fos.close();
  38.                 } catch (IOException e) {
  39.                     Log.e(TAG, e.toString());
  40.                     }
  41.                 }
  42.                 fos = null;
  43.             }
  44.      Log.d("test","saved:"+saved);
  45.         return saved;
  46.     }

     好了,这样在client端的sd卡的根目录中新建一个test.txt文件,当两个手机连接起来后,client端随便发送一个字符串就可以触发传输文件的操作了。

 



 
 
 
 





  通过alljoyn传输文件(2)  2012-12-19 14:39:41

分类: 嵌入式

     上一篇文章介绍了使用alljoyn的raw方式进行文件的传输,其实那种方法不是很实用,并不是一种好的方式,这篇文章介绍一下使用alljoyn的signal方式进行文件的传输。
     在alljoyn的sdk里面有个chat的例子,这个例子就是使用signal传输手机间的聊天信息的。我们所要做的就是将其修改一下来传输我们的文件。
     首先修改ChatInterface.java里面的接口,将参数从string 类型改成byte[]类型,如下所示:

点击(此处)折叠或打开

  1. public void Chat(byte[] str) throws Bu***ception;
     这就表示我们传输的不是字符串而是byte数组了。所以接下来的问题就是将文件内容转换成一系列的byte数组发出去然后接收这些byte数组并重新组成文件就可以了。首先来看发送,发送时在AllJoynService.java的doSendMessages()方法。


点击(此处)折叠或打开

  1. try {
  2.                 if (mJoinedToSelf) {
  3.                     if (mHostChatInterface != null) {
  4.                         // mHostChatInterface.Chat(message);

  5.                     }
  6.                 } else {
  7.                     SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss ");
  8.                     Date curDate = new Date(System.currentTimeMillis());// 获取当前时间

  9.                     String str = formatter.format(curDate);
  10.                     Log.d("test", "start:" + str+"::::");
  11.                     String filepath = "/sdcard/Picture/100ANDRO/MOV_0426.mp4";
  12.                     File file = new File(filepath);
  13.                     InputStream in = null;
  14.                     try {
  15.                         in = new FileInputStream(file);
  16.                     } catch (FileNotFoundException e1) {
  17.                         // TODO Auto-generated catch block

  18.                         e1.printStackTrace();
  19.                     }
  20.                     byte[] buffer = new byte[102400];
  21.                     int read = 0;
  22.                     while ((read = in.read(buffer)) != -1) {
  23.                         mChatInterface.Chat(buffer);
  24.                         buffer = new byte[102400];
  25.                     }
  26.                     in.close();
  27.                     curDate = new Date(System.currentTimeMillis());// 获取当前时间

  28.                     str = formatter.format(curDate);
  29.                     Log.d("test", "end:" + str+"::::");
  30.                 }
  31.             } catch (Bu***ception ex) {
  32.                 mChatApplication.alljoynError(ChatApplication.Module.USE,
  33.                         "Bus exception while sending message: (" + ex + ")");
  34.             } catch (IOException e) {
  35.                 Log.d("test", e.toString());
  36.             }
      在发送的前后加上系统的时间这样就可以测试发送文件花费的时间。接收是在Chat(byte[] string) 方法里面。

点击(此处)折叠或打开

  1. public void Chat(byte[] string) {

  2.         /*
  3.          * See the long comment in doJoinSession() for more explanation of why
  4.          * this is needed.
  5.          * 
  6.          * The only time we allow a signal from the hosted session ID to pass
  7.          * through is if we are in mJoinedToSelf state. If the source of the
  8.          * signal is us, we also filter out the signal since we are going to
  9.          * locally echo the signal.
  10.          */
  11.         String uniqueName = mBus.getUniqueName();
  12.         MessageContext ctx = mBus.getMessageContext();
  13.         Log.i(TAG, "Chat(): use sessionId is " + mUseSessionId);
  14.         Log.i(TAG, "Chat(): message sessionId is " + ctx.sessionId);

  15.         /*
  16.          * Always drop our own signals which may be echoed back from the system.
  17.          */
  18.         if (ctx.sender.equals(uniqueName)) {
  19.             Log.i(TAG, "Chat(): dropped our own signal received on session "
  20.                     + ctx.sessionId);
  21.             return;
  22.         }

  23.         /*
  24.          * Drop signals on the hosted session unless we are joined-to-self.
  25.          */
  26.         if (mJoinedToSelf == false && ctx.sessionId == mHostSessionId) {
  27.             Log.i(TAG, "Chat(): dropped signal received on hosted session "
  28.                     + ctx.sessionId + " when not joined-to-self");
  29.             return;
  30.         }

  31.         /*
  32.          * To keep the application simple, we didn't force users to choose a
  33.          * nickname. We want to identify the message source somehow, so we just
  34.          * use the unique name of the sender's bus attachment.
  35.          */
  36.         String nickname = ctx.sender;
  37.         nickname = nickname
  38.                 .substring(nickname.length() - 10, nickname.length());

  39.         // Log.i(TAG, "Chat(): signal " + string + " received from nickname " +

  40.         // nickname);

  41. //        mChatApplication.newRemoteUserMessage(nickname, "get message");

  42.         try {
  43.             try {
  44.                 if (file == null) {
  45.                     file = new File("/mnt/sdcard/abc.mp4");
  46.                 }
  47.                 fos = new FileOutputStream(file, true);
  48.             } catch (Exception e) {
  49.                 Log.e(TAG, "creat file error");
  50.             }
  51.             try {
  52.                 fos.write(string, 0, string.length);
  53.             } catch (IOException e) {
  54.                 Log.e(TAG, "write file error");
  55.             }

  56.         } finally {
  57.             if (fos != null) {
  58.                 try {
  59.                     fos.close();
  60.                 } catch (IOException e) {
  61.                     Log.e(TAG, e.toString());
  62.                 }
  63.             }
  64.             fos = null;
  65.         }
  66.     }
       这样就可以进行文件的传输了,测试表明这个方法比上个方法更快更稳定了。
 








你可能感兴趣的:(通过alljoyn传输文件)