提高java / android中TCP套接字的传输速度

时间:2013-04-17 11:48:37

标签: java android sockets tcp wifi-direct

我正在开发基于wifi直接的文件传输应用程序。我可以看到使用TCP套接字的传输速度并不令人满意。速度通常为1Mbps。每当我分析数据传输图时,我都会看到很多尖峰,很多秒都没有数据传输。我知道传输速度应该更高(可能是20-30Mbps) 请帮我提高传输速度。 接受连接的serversocket是

private void serverTask() {
        Log.v(TAG, "server task");
        try {
            serverRunning = true;
            ServerSocket serverSocket = new ServerSocket(
                    DeviceDetailFragment.PORT);
            serverSocket.setReceiveBufferSize(TCP_BUFFER_SIZE);


            Socket client = serverSocket.accept();

            BufferedInputStream inputstream = new BufferedInputStream(
                    client.getInputStream());
            // new BufferedInputStream(client.getInputStream(), 8 * 1024);
            BufferedReader bufferedStream = new BufferedReader(
                    new InputStreamReader(inputstream));


                fileName = bufferedStream.readLine();
                fileSizeInBytes = bufferedStream.readLine();
                fileMime = bufferedStream.readLine();

                f = new File(Globals.fileSavingLocation + fileName);

                File dirs = new File(f.getParent());
                if (!dirs.exists())
                    dirs.mkdirs();

                if (f.exists()) {
                    f.delete();
                }

                f.createNewFile();

        IOUtils.copy(inputstream, new FileOutputStream(f));


                serverSocket.close();
            }
            isSuccessful = true;

        } catch (IOException e) {
            isSuccessful = false;
            Log.e(TAG, e.getMessage());

        }
        serverRunning = false;

    }

发送数据的客户端有以下代码:

 private void clientTask(Intent intent) {
            String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
            String host = intent.getExtras().getString(EXTRAS_ADDRESS);
            String fileName = intent.getExtras().getString(FILE_NAME);
            String fileMimeType = intent.getExtras().getString(FILE_MIME_TYPE);
            final long sizeInBytes = intent.getExtras().getLong(FILE_SIZE);
            Socket socket = new Socket();
            int port = intent.getExtras().getInt(EXTRAS_PORT);

            try {
                socket.setSendBufferSize(TCP_BUFFER_SIZE);
                socket.bind(null);
                socket.connect((new InetSocketAddress(host, port)),
                        SOCKET_TIMEOUT);

                BufferedOutputStream stream = new BufferedOutputStream(
                        socket.getOutputStream());
                ContentResolver cr = FileTransferService.this
                        .getApplicationContext().getContentResolver();
                InputStream is = null;

                BufferedWriter bufferStream = new BufferedWriter(
                        new OutputStreamWriter(stream));


                bufferStream.write(fileName);
                bufferStream.newLine();
                bufferStream.flush();
                bufferStream.write(String.valueOf(sizeInBytes));
                bufferStream.newLine();
                bufferStream.flush();

                bufferStream.write(fileMimeType);
                bufferStream.newLine();
                bufferStream.flush();


                try {

                    is = new BufferedInputStream(cr.openInputStream(Uri
                            .parse(fileUri)));

                } catch (FileNotFoundException e) {

                    isSuccessful = false;

                }
 IOUtils.copy(is, stream);


                isSuccessful = true;

            } catch (IOException e) {
                Log.e(TAG, e.getMessage());
                isSuccessful = false;
            } finally {
                if (socket != null) {
                    if (socket.isConnected()) {
                        try {
                            socket.close();
                        } catch (IOException e) {
                            // Give up
                            e.printStackTrace();
                        }
                    }
                }
            }

TCP_BUFFER_SIZE的值设置为1024*512

我已经尝试了很多改变TCP_BUFFER_SIZE的值,但没有运气。我用Apache Commons IOUtils替换了我的复制流实现。 帮帮我

更新: 请参阅以下转移图表 Graph of transfer speed

2 个答案:

答案 0 :(得分:2)

您似乎正在从setReceiveBufferSize() javadoc

重载缓冲区
  

可以通过调用随后更改值   socket的(INT)。但是,如果申请愿意   允许接收窗口大于64K字节,如RFC1323所定义   那么建议的值必须先在ServerSocket中设置   绑定到本地地址。这意味着,ServerSocket必须是   使用无参数构造函数创建,然后使用setReceiveBufferSize()   必须被调用,最后ServerSocket绑定到一个地址   调用bind()。

答案 1 :(得分:0)

我会尝试使用普通Socket进行简单的数据传输而不使用文件。

有一个简单的服务器,当你连接时发送100 MB的空数据。让客户端尽可能快地读取数据,并报告其获得的吞吐量。在同一台机器上,您应该可以轻松看到超过100 MB / s。一旦这给出了一个好的数字,请在Android客户端上尝试。