Android套接字文件传输

5
需要帮助...我已经理解了如何建立服务器-客户端套接字连接...它可以正常工作...现在我想从服务器向客户端传输文件,然后再传回来...这是我的源代码...
套接字服务器...
public class ServerActivity extends Activity {

private TextView serverStatus;

// default ip
public static String SERVERIP = "192.168.1.1";

// designate a port
public static final int SERVERPORT = 8080;

private Handler handler = new Handler();

private ServerSocket serverSocket;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    serverStatus = (TextView) findViewById(R.id.server_status);

    SERVERIP = getLocalIpAddress();

    Thread fst = new Thread(new ServerThread());
    fst.start();
}

public class ServerThread implements Runnable {

    public void run() {
        try {
            if (SERVERIP != null) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        serverStatus.setText("Listening on IP: " + SERVERIP);
                    }
                });
                serverSocket = new ServerSocket(SERVERPORT);
                while (true) {
                    // listen for incoming clients


                    Socket client = serverSocket.accept();
                    /////////////////////////////////
                    File myFile = new File ("/sdcard/frostwire.apk");
                    byte [] mybytearray  = new byte [(int)myFile.length()];
                    FileInputStream fis = new FileInputStream(myFile);
                    BufferedInputStream bis = new BufferedInputStream(fis);
                    bis.read(mybytearray,0,mybytearray.length);
                    OutputStream os = client.getOutputStream();
                    System.out.println("Sending...");
                    serverStatus.setText("sending 123.exe...");
                    os.write(mybytearray,0,mybytearray.length);
                    os.flush();
                    client.close();
                    ////////////////////////////

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            serverStatus.setText("Connected.");
                        }
                    });

                    try {
                        BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                        String line = null;
                        while ((line = in.readLine()) != null) {
                            Log.d("ServerActivity", line);
                            handler.post(new Runnable() {
                                @Override
                                public void run() {
                                    // do whatever you want to the front end
                                    // this is where you can be creative
                                }
                            });
                        }
                        break;
                    } catch (Exception e) {
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                serverStatus.setText("Oops. Connection interrupted. Please reconnect your phones.");
                            }
                        });
                        e.printStackTrace();
                    }
                }
            } else {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        serverStatus.setText("Couldn't detect internet connection.");
                    }
                });
            }
        } catch (Exception e) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    serverStatus.setText("Error");
                }
            });
            e.printStackTrace();
        }
    }
}

// gets the ip address of your phone's network
private String getLocalIpAddress() {
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress()) { return inetAddress.getHostAddress().toString(); }
            }
        }
    } catch (SocketException ex) {
        Log.e("ServerActivity", ex.toString());
    }
    return null;
}

@Override
protected void onStop() {
    super.onStop();
    try {
         // make sure you close the socket upon exiting
         serverSocket.close();
     } catch (IOException e) {
         e.printStackTrace();
     }
}

} 

Socket客户端...

public class ClientActivity extends Activity {

private EditText serverIp;

private Button connectPhones;

private String serverIpAddress = "";

private boolean connected = false;

private Handler handler = new Handler();
int filesize; // filesize temporary hardcoded

long start = System.currentTimeMillis();
int bytesRead;
int current = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.client);

    serverIp = (EditText) findViewById(R.id.server_ip);
    connectPhones = (Button) findViewById(R.id.connect_phones);
    connectPhones.setOnClickListener(connectListener);
}

private OnClickListener connectListener = new OnClickListener() {

    @Override
    public void onClick(View v) {
        if (!connected) {
            serverIpAddress = serverIp.getText().toString();
            if (!serverIpAddress.equals("")) {
                Thread cThread = new Thread(new ClientThread());
                cThread.start();
            }
        }
    }
};

public class ClientThread implements Runnable {

    public void run() {
        try {
            InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
            Log.d("ClientActivity", "C: Connecting...");
            Socket socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
            connected = true;
    //////////     // receive file
            byte [] mybytearray  = new byte [filesize];
            InputStream is = socket.getInputStream();
            FileOutputStream fos = new FileOutputStream("/sdcard/frostwire.apk");
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            bytesRead = is.read(mybytearray,0,mybytearray.length);
            current = bytesRead;


            do {
               bytesRead =
                  is.read(mybytearray, current, (mybytearray.length-current));
               if(bytesRead >= 0) current += bytesRead;
            } while(bytesRead > -1);

            bos.write(mybytearray, 0 , current);
            bos.flush();
            long end = System.currentTimeMillis();
            System.out.println(end-start);
            bos.close();
            socket.close();

     //////////////////////////////       
            while (connected) {
                try {
                    Log.d("ClientActivity", "C: Sending command.");
                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                                .getOutputStream())), true);
                        // where you issue the commands
                        out.println("Hey Server!");
                        Log.d("ClientActivity", "C: Sent.");
                } catch (Exception e) {
                    Log.e("ClientActivity", "S: Error", e);
                }
            }
            socket.close();
            Log.d("ClientActivity", "C: Closed.");
        } catch (Exception e) {
            Log.e("ClientActivity", "C: Error", e);
            connected = false;
        }
    }
}
}

被标记为“///////”的源代码部分不起作用...求助


Socket服务器出现错误...据我所知,问题出在: - timonvlad
在服务器和客户端的一侧... - timonvlad
更多细节......使用此代码,我的客户端从SD卡中获取文件并开始发送......同时,在日志记录中发生错误......然后,这个开始传输的文件在SD卡上变成了0 KB。 - timonvlad
客户端和服务器都在同一部手机上运行吗?那么当客户端尝试读取文件时,服务器会覆盖该文件! - Some programmer dude
不!!!服务器在HTC Desire Android 2.2上,客户端在三星Galaxy Tab 1 Android 2.2上。 - timonvlad
显示剩余4条评论
2个回答

1


最好你把以下的代码替换掉

do {
               bytesRead =
                  is.read(mybytearray, current, (mybytearray.length-current));
               if(bytesRead >= 0) current += bytesRead;
            } while(bytesRead > -1);

使用以下的一个

do {
               bytesRead =is.read(mybytearray, current, (mybytearray.length-current));
               if(bytesRead > 0)
               {
                    current += bytesRead;
               }
   } while(bytesRead > 0);


那就试试吧


0

在阅读了以上讨论后,我想补充几点意见:

  1. 您是否在Android清单文件中添加了读取SD卡的权限代码?如果没有,请添加以下代码,因为服务器正在访问外部存储。客户端也应该这样做,以便在外部存储中进行写入。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

  1. 否则,您提供的目录不正确。请检查目录。

  2. 在客户端程序中,您定义了一个file_size变量,但是在程序中没有任何值被赋值给它。

  3. 我还想建议一下,客户端程序中的file_size应该大于要传输的文件大小,且以字节为单位。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接