android:通过套接字传输文件

标签 android

您好,我正在尝试通过 Android Messenger 中的套接字发送文件。由于某种原因,它不起作用。有时它确实输出文件但不传输任何字节,即输出文件为 0 字节,有时输出或接收的文件恰好为 57 字节。按照我实际发送文件的代码:

public boolean sendFile(String ip, int port) {      
     try {                      
         String[] str = ip.split("\\.");
         byte[] IP = new byte[str.length];
         for (int i = 0; i < str.length; i++) {
             IP[i] = (byte) Integer.parseInt(str[i]);
         }
         Socket socket = getSocket(InetAddress.getByAddress(IP), port);
         if (socket == null) {
             return false;
         }
         Log.i("SocketOP", "sendFILE-1");
         File  f = new File("/sdcard/chats/gas.jpg/");
         filesize = (int) f.length();

         BufferedOutputStream out = new BufferedOutputStream( socket.getOutputStream() );

         FileInputStream fileIn = new FileInputStream(f);
         Log.i("SocketOP", "sendFILE-2");
         byte [] buffer  = new byte [filesize];
         int bytesRead =0;
         while ((bytesRead = fileIn.read(buffer)) > 0) {
             out.write(buffer, 0, bytesRead);
         }
         out.flush();
         out.close();
         fileIn.close();
         Log.i("SocketOP", "sendFILE-3");
     } catch (IOException e) {
         return false;          
         //e.printStackTrace();
     }
     return true;       
 }  

这是我将输入流发送到 receivefile 方法的地方:

private class ReceiveConnection extends Thread {

    Socket clientSocket = null;
    public ReceiveConnection(Socket socket) {
        this.clientSocket = socket;
        SocketOperator.this.sockets.put(socket.getInetAddress(), socket);
    }

    @Override
    public void run() {
        try {
            //PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(
                clientSocket.getInputStream()));
            String inputLine;

            while ((inputLine = in.readLine()) != null) {
                InputStream is=clientSocket.getInputStream();
                if (inputLine.contains("Text") == true) {
                    appManager.messageReceived(inputLine);  
                    Log.i("SocketOP","text");

                } else if (inputLine.contains("Text") == false) {
                        Log.i("SocketOP","filee");
                        appManager.fileReceived(is);
                } else {
                    clientSocket.shutdownInput();
                    clientSocket.shutdownOutput();
                    clientSocket.close();
                    SocketOperator.this.sockets.remove(clientSocket.getInetAddress());
                    Log.i("SocketOP", "CLOSING CONNECTION");
                }                        
            }
        }
    }
}

最后这就是我收到文件的方式:

public void fileReceived(InputStream is)
    throws FileNotFoundException, IOException {
    Log.i("IMSERVICE", "FILERECCC-1");

    //int filesize=6022386; // filesize temporary hardcoded

    int bytesRead;

    final byte[] aByte = new byte[is.toString().length()];


    if (is!= null) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            fos = new FileOutputStream("/sdcard/chats/gas1.jpg/");
            bos = new BufferedOutputStream(fos);
            bytesRead = is.read(aByte, 0, aByte.length);

            do {
                baos.write(aByte);
                bytesRead = is.read(aByte);
            } while (bytesRead != -1);

            bos.write(baos.toByteArray());
            bos.flush();
            bos.close();
            Log.i("IMSERVICE", "FILERECCC-2");

        } catch (IOException ex) {
            // Do exception handling
        }
    }
}}

完整的socketoperator文件如下:

package hardy.scl.communication;

import hardy.scl.interfaces.IAppManager;
import hardy.scl.interfaces.ISocketOperator;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Iterator;

import android.util.Log;


public class SocketOperator implements ISocketOperator
{
private static final String AUTHENTICATION_SERVER_ADDRESS = "http://10.10.10.100/chippers/";

private int listeningPort = 0;

private static final String HTTP_REQUEST_FAILED = null;



private HashMap<InetAddress, Socket> sockets = new HashMap<InetAddress, Socket>();

private ServerSocket serverSocket = null;

private boolean listening;

private IAppManager appManager;

public int filesize ;



private class ReceiveConnection extends Thread {
Socket clientSocket = null;
Socket fileSocket=null;
public ReceiveConnection(Socket socket) 
{
    this.clientSocket = socket;
    this.fileSocket=socket;
    SocketOperator.this.sockets.put(socket.getInetAddress(), socket);
}

@Override
public void run() {
     try {
//          PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),    true);
        BufferedReader in = new BufferedReader(
                   new InputStreamReader(
                            clientSocket.getInputStream()));



         InputStream is=fileSocket.getInputStream();

        String inputLine;
        while ((inputLine = in.readLine()) != null)                  {



             if (inputLine.contains("Text") == true)
             {


                appManager.messageReceived(inputLine);  
        Log.i("SocketOP","text");}

             else  if 
            (inputLine.contains("Text") == false)
            {

                Log.i("SocketOP","filee");
                 appManager.fileReceived(is);

             }
            else{

                 clientSocket.shutdownInput();
                 clientSocket.shutdownOutput();
                 clientSocket.close();

                 fileSocket.shutdownInput();
                 fileSocket.shutdownOutput();
                 fileSocket.close();
                      SocketOperator.this.sockets.remove(clientSocket.getInetAddress());
                 SocketOperator.this.sockets.remove(fileSocket.getInetAddress());

                 Log.i("SocketOP", "CLOSING CONNECTION");
             }                       
    }       

    } catch (IOException e) {
        Log.e("ReceiveConnection.run: when receiving connection ","");
}           
}   
}

public SocketOperator(IAppManager appManager) {
this.appManager = appManager;   
}


public String sendHttpRequest(String params)
{       
URL url;
String result = new String();
try 
{
    url = new URL(AUTHENTICATION_SERVER_ADDRESS);
    HttpURLConnection connection;
    connection = (HttpURLConnection) url.openConnection();
    connection.setDoOutput(true);

    PrintWriter out = new PrintWriter(connection.getOutputStream());

    out.println(params);
    out.close();

    BufferedReader in = new BufferedReader(
            new InputStreamReader(
                    connection.getInputStream()));
    String inputLine;

    while ((inputLine = in.readLine()) != null) {
        result = result.concat(inputLine);              
    }
    in.close();         
} 
catch (MalformedURLException e) {
    e.printStackTrace();
} 
catch (IOException e) {
    e.printStackTrace();
}           

if (result.length() == 0) {
    result = HTTP_REQUEST_FAILED;
}

return result;


}


public boolean sendMessage(String message, String ip, int port) 
{
try {


    String[] str = ip.split("\\.");

    byte[] IP = new byte[str.length];

    for (int i = 0; i < str.length; i++) {

        IP[i] = (byte) Integer.parseInt(str[i]);                
    }
    Socket socket = getSocket(InetAddress.getByAddress(IP), port);
    if (socket == null) {
        return false;
    }

    PrintWriter out = null;
    out = new PrintWriter(socket.getOutputStream(), true);
    //OutputStreamWriter outputStream = new OutputStreamWriter(socket.getOutputStream());
    //outputStream.write("Text");
   // outputStream.flush();
    String flag = "Text";
    message = message+flag;
    out.println(message);
} catch (UnknownHostException e) {          
    return false;
    //e.printStackTrace();
} catch (IOException e) {
    return false;           
    //e.printStackTrace();
}

return true;        
}




public int startListening(int portNo) 
{
listening = true;

try {
    serverSocket = new ServerSocket(portNo);
    this.listeningPort = portNo;
} catch (IOException e) {           

    //e.printStackTrace();
    this.listeningPort = 0;
    return 0;
}

while (listening) {
    try {
        new ReceiveConnection(serverSocket.accept()).start();

    } catch (IOException e) {
        //e.printStackTrace();              
        return 2;
    }
}

try {
    serverSocket.close();
} catch (IOException e) {           
    Log.e("Exception server socket", "Exception when closing server socket");
    return 3;
}


return 1;
}


public void stopListening() 
{
this.listening = false;
}

private Socket getSocket(InetAddress addr, int portNo) 
{
Socket socket = null;
if (sockets.containsKey(addr) == true) 
{
    socket = sockets.get(addr);
    // check the status of the socket
    if  ( socket.isConnected() == false ||
          socket.isInputShutdown() == true ||
          socket.isOutputShutdown() == true ||
          socket.getPort() != portNo 
         )  
    {           
        // if socket is not suitable,  then create a new socket
        sockets.remove(addr);               
        try {
            socket.shutdownInput();
            socket.shutdownOutput();
            socket.close();
            socket = new Socket(addr, portNo);
            sockets.put(addr, socket);
        } 
        catch (IOException e) {                 
            Log.e("getSocket: when closing and removing", "");
        }               
    }
}
else  
{
    try {
        socket = new Socket(addr, portNo);
        sockets.put(addr, socket);
    } catch (IOException e) {
        Log.e("getSocket: when creating", "");              
    }                   
}
return socket;      
}


public void exit() 
{           
for (Iterator<Socket> iterator = sockets.values().iterator(); iterator.hasNext();) 
{
    Socket socket = (Socket) iterator.next();
    try {
        socket.shutdownInput();
        socket.shutdownOutput();
        socket.close();
    } catch (IOException e) 
    {               
    }       
}

sockets.clear();
this.stopListening();
appManager = null;
//      timer.cancel();     
}


public int getListeningPort() {

return this.listeningPort;
}


@Override
public boolean sendFile(String ip, int port) {
// TODO Auto-generated method stub


try {


    String[] str = ip.split("\\.");

    byte[] IP = new byte[str.length];

    for (int i = 0; i < str.length; i++) {

        IP[i] = (byte) Integer.parseInt(str[i]);


    }
    Socket socket = getSocket(InetAddress.getByAddress(IP), port);
    if (socket == null) {
        return false;
    }
    Log.i("SocketOP", "sendFILE-1");
   File  f = new File("/sdcard/chats/gas.jpg/");



   BufferedInputStream bis = new BufferedInputStream(new FileInputStream(f));
int readData;
   byte[] buffer = new byte[1024];   
   bis.read(buffer, 0,buffer.length);
  OutputStream os = socket.getOutputStream();

  while((readData=bis.read(buffer))!=-1){
      os.write(buffer,0,readData);


   Log.i("SocketOP", "sendFILE-3");
   }









} catch (IOException e) {
    return false;           
    //e.printStackTrace();
}
//  Toast.makeText(this, "Lvbvhhging...", Toast.LENGTH_SHORT).show();

return true;        
}
}   

这是我运行并调用 startlistening 的 IMService 服务。我完全不知所措。它给了我一个怀疑的错误。我现在该如何解决这个问题.. IMService 代码块:

public void onCreate() 
{       
     mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

    // Display a notification about us starting.  We put an icon in the status bar.
 //   showNotification();
    conManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);


    // Timer is used to take the friendList info every UPDATE_TIME_PERIOD;
    timer = new Timer();   

    Thread thread = new Thread()
    {
        @Override
        public void run() {         

            //socketOperator.startListening(LISTENING_PORT_NO);
            Random random = new Random();
            int tryCount = 0;
            while (socketOperator.startListening(10000 +     random.nextInt(20000))      == 0 )
            {       
                tryCount++; 
                if (tryCount > 10)
                {
                    // if it can't listen a port after trying 10 times,    give up...
                    break;
                }

            }
        }
    };      
    thread.start();

}

最佳答案

试试这个 fileReceived

public void fileReceived(InputStream is)
    throws FileNotFoundException, IOException {
    Log.i("IMSERVICE", "FILERECCC-1");


    if (is!= null) {
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            fos = new FileOutputStream("/sdcard/chats/gas1.jpg/");
            bos = new BufferedOutputStream(fos);
            byte[] aByte = new byte[1024];
            int bytesRead;

            while ((bytesRead = is.read(aByte)) != -1) {
                bos.write(aByte, 0, bytesRead);
            }
            bos.flush();
            bos.close();
            Log.i("IMSERVICE", "FILERECCC-2");

        } catch (IOException ex) {
            // Do exception handling
        }
    }
}}

编辑

您可以使用 2 个套接字,监听不同的端口。例如

MESSAGE_PORT = 20000
FILE_PORT = 20001

然后您运行 2 个 ReceiveConnection,例如ReceiveFileConnectionReceiveMessageConnection。我不知道你从哪里开始端口监听,它不在你上面​​的代码中。

在客户端中,您还需要将发送分成两部分,消息发送者发送到 MESSAGE_PORT,文件发送文件到 FILE_PORT。

EDIT2

http://pastebin.com/MfMuSF2Q

  • 我将 ReceiveConnection 分成 2 个类 ReceiveMessageConnectionReceiveFileConnection
  • 我修改了方法startListening,所以它接受我们想要启动消息或文件的监听器的参数。所以你需要像这样调用它两次

    开始监听(MESSAGE_PORT,真);

    startListening(FILE_PORT, false);

但是在不同的线程中调用它们。

要发送消息,您调用 sendMessage("Message", ip, MESSAGE_PORT) 并为文件调用 sendFile(ip, FILE_PORT)

希望这会有所帮助。

关于android:通过套接字传输文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7181017/

相关文章:

android - 统一注销UnityEngine.Social

android studio 3.1 总是收到关于无法解析依赖的错误

java - Android - 当我删除列表项时应用程序崩溃

android - 在 FrameLayout 中的自定义 View 上以编程方式设置边距值

java - 关于使用android获取IMEI,有以下错误

java - 在 android graphview 中添加背景图像

android - 如何使用 sendevent 或其他方式模拟来自后台服务的触摸?

java - "Method call expected"int数组的length方法错误

java - Android API 2.2.1 是否过时而无法使用?

java - Enum.values() 从何而来?