我如何以约40%的永久性速率解决Android客户端Java服务器代码



[编辑以解释这个已发布的问题不是引用问题的重复:::

  1. 引用问题中代码中代码中的结构,详细信息和例程与我的不同。此外,他正在发送多个文件并在核心中使用arraylist。当我的代码一次发送一个文件时,我从未在核心中使用arraylist。因此,导致我偶尔障碍的原因可能不会与他/她自己的代码的问题重叠

  2. 在第一个答案中,EJP说"您正在阅读插座,直到read((返回((返回-1。" 我没有在代码中执行此操作

  3. 在第一个答案中,EJP说"您需要在每个文件前发送文件大小。该文件的确切多个字节:" 我已经在我的原始发布的代码中发送的文件前发送了精确的文件大小,因此这不是我的代码的问题,因此也不是解决问题的解决方案我面对

  4. 第二个答案中的代码(在引用的重复中(具有不同的目的,因此我无法将解决方案从其代码中推断为我自己的代码。

  5. 引用的问题说"后续文件是在服务器文件夹中创建的,但是它们是0个字节" 这不是我自己的代码的问题。当我的代码运行时,我会在客户端和服务器结束时收到完整的文件字节。

  6. 我已经阅读了所有引用的问题和所提供的解决方案,并且它们没有为我面临的问题提供任何解决方案

谢谢]

我对客户端服务器编码是相对较新的。我将Android作为客户端和Java服务器。目前的系统工作如下::Android客户端从SDCard选择/加载JPEG映像,将int size,字符串文本和图像文件发送到服务器和服务器发送回到整数,以及带有数据的文本文件回到客户端

目前,我的问题正常工作(随机(约60%的运行。其余时间>永久阻止,我必须重新启动服务器才能继续。[当然,一半以上的时间,客户服务器系统发送和接收而无需小故障,但〜40%至45%(永久块(失败率是不可接受的]

当它阻止时,没有碰撞转储,堆栈或错误要读取。我已经搜索了以前的类似阻止问题,并试图在不同订单中关闭插座和输入流/输出流和包装器,以改变排列,但成功/永久块率保持相同

由于没有堆栈跟踪和随机性,所以我不知道是什么原因导致块。除了使用打印语句使用所有服务器和客户端代码,最后悬挂的最后一个打印位于 bytes中,接收do-whe lile loop 在服务器代码

我对解决这个问题感到不知所措。我希望这个领域有经验的思想能够帮助解决这一问题。完整代码在下面。

Java服务器代码

public class FileServer {                 
  public static  void main(String[] args) throws IOException {
      int bytesRead;     
      int current = 0;   
     //===============================================
      FileInputStream fis = null;
      BufferedInputStream bis = null;
      OutputStream os = null;           
      ServerSocket servsock = null;
      Socket sock = null;                 
      //==============================================
      InetAddress IP=InetAddress.getLocalHost();   
      servsock = new ServerSocket(57925);      
      System.out.println("IP "+IP.getHostAddress()+"  ***%% :"+servsock.getLocalPort());  
      while (true) {      
        sock = servsock.accept();
        System.out.println("Accepted connection : " + sock);
          InputStream is = sock.getInputStream();
 //=========================================================
          InputStreamReader isr = new InputStreamReader(is);
          BufferedReader br = new BufferedReader(isr);
 //=================== read integer from client ============
          String number = br.readLine();
          System.out.println("integer received from client is "+String.valueOf(number));
           byte [] mybytearray  = new byte [Integer.valueOf(number)];
 //=================== read filename string =====================================  
           String filename = br.readLine();
           System.out.println("integer received from client is "+filename);
//===================== read file data stream bytes ================================
         bytesRead = is.read(mybytearray,0,mybytearray.length);
         current = bytesRead;
         System.out.println("1  bytesRead  "+bytesRead+"  mybytearray.length  "+mybytearray.length);
         do {
             bytesRead =  is.read(mybytearray, current, (mybytearray.length-current));
             if(bytesRead >= 0) current += bytesRead;
             System.out.println("2  current  "+current+"  bytesRead  "+bytesRead);
        } while(current < Integer.valueOf(number));         

        //============================== initialise filename ======================             
          FileOutputStream fos = new FileOutputStream("C:\Server root folder\"+filename+".jpg"); 
          BufferedOutputStream bos = new BufferedOutputStream(fos);
         //========================== write bytes to server HDD =======================       
          bos.write(mybytearray, 0 , current);
          System.out.println("4  current  "+current);
          bos.flush();
          long end = System.currentTimeMillis();   
//          System.out.println("AT SERVER: bytesRead  "+bytesRead+"  current  "+current);
//          bos.close();  
// ======================== write to-be-rendered data to text file ====================== 
          File pathPlusfile = new File("C:/Server root folder/"+filename+".txt");
          appendToFile( pathPlusfile, "file name::  "+filename+"*   *", 20999  );

/**/  //==================   Send Data in text file to Client  ============================================              
          // send file     
          mybytearray  = new byte [(int)pathPlusfile.length()];
          fis = new FileInputStream(pathPlusfile);
          bis = new BufferedInputStream(fis);
          bis.read(mybytearray,0,mybytearray.length);
 //===============================================   
          os = sock.getOutputStream();
//=========================== send integer to client ===============                   
          OutputStreamWriter osw = new OutputStreamWriter(os);
          BufferedWriter bw = new BufferedWriter(osw);
          number = Integer.toString(mybytearray.length);
          String sendMessage = number + "n";
          bw.write(sendMessage);
          bw.flush();   
//========================== send file to client ===================                
          System.out.println("Sending " + filename + "(" + mybytearray.length + " bytes)");
          os.write(mybytearray,0,mybytearray.length);
          os.flush();
    //========================= close =================================      
          System.out.println("number  "+number);
          System.out.println("Done.");
          bos.close();
          bw.close();
          osw.close();
          os.close();
 //         fos.close();
 //         bis.close();
//          fis.close();
 //         br.close();
          isr.close();
          is.close();
          closeFile(  );               
//           servsock.close();
//           sock.close(); 
     }
  }
  BufferedReader bufferedReader = null;
  String stringObjectData = "";
  public int  numFromFile = 0;

     static BufferedWriter  bufferedWriter = null;
    public static  void appendToFile( File myPathPlusFile, String S, int num  ){
       try{
          bufferedWriter = new BufferedWriter(new FileWriter(myPathPlusFile, true));
          bufferedWriter.append( S ); 
          bufferedWriter.append( "     " ); 
          bufferedWriter.append( Integer.toString(num) ); 
          bufferedWriter.newLine();
          bufferedWriter.flush();
       }
       catch (IOException e){
          e.printStackTrace();
       }
     }
     public static  void closeFile(  ){
       try{
          bufferedWriter.close();
       }
       catch (IOException e)
       {
          e.printStackTrace();
       }
    }
}

Android客户端代码

public class FSendfileActivity extends Activity {
    private static final int SELECT_PICTURE = 1;
    private Socket sock;
    private String serverIP = "192.168.1.4";    
    private String selectedImagePath;
    private ImageView img;
    final static String qcd = "qcd";
    String ImageDir2Client;      
    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    Button send;
//====================
    public  static String   FILE_TO_RECEIVED=null;
    String cFilename = null;
    int bytesRead = -1;
    int current = 0;                 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fsendfile);    
        ImageDir2Client = Environment.getExternalStorageDirectory().getAbsolutePath();                    
        cFilename = "fromServer000019ggg";
        FILE_TO_RECEIVED = ImageDir2Client + "/client root/"+cFilename+".txt";  

        img  = (ImageView) findViewById(R.id.ivPic);  
       ((Button) findViewById(R.id.bBrowse)).setOnClickListener(new OnClickListener() {
           public void onClick(View arg0) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult( Intent.createChooser( intent, "Select Picture" ), SELECT_PICTURE );
            }
       });
       send = (Button) findViewById(R.id.bSend);
       send.setOnClickListener(new View.OnClickListener() {
           @Override                     
           public void onClick(View arg0) {
            new Thread(new Runnable() {                  
                   @Override        
                   public void run() {            
                       try {                                     
                        sock = new Socket();     
                        connection(sock,  serverIP, 57925);
            //=================== prepare buffer to read file ====================
                            File myFile = new File (selectedImagePath); 
                            byte [] mybytearray  = new byte [(int)myFile.length()];
                            FileInputStream fis = new FileInputStream(myFile);
                            BufferedInputStream bis = new BufferedInputStream(fis);
                       //=============== read file from sdcard to buffer ==========     
                            bis.read(mybytearray,0,mybytearray.length);
            //=================================================================                   
                            OutputStream os = sock.getOutputStream();
                            OutputStreamWriter osw = new OutputStreamWriter(os);
                            BufferedWriter bw = new BufferedWriter(osw);
            //============================= send size integer ===================                
                            String number = Integer.toString(mybytearray.length);
                            String sendMessage = number + "n";
                            bw.write(sendMessage);   // send size integer here
            //============================= send file name =====================
                            String sendMessage2 = cFilename + "n";
                            bw.write(sendMessage2);   // send size filename here
                            osw.flush();
                            bw.flush();
            //==================================================================                
                            os.write(mybytearray,0,mybytearray.length); // send file
                            os.flush();  
    //=================  client receiving data ==============================
                        InputStream is = sock.getInputStream();
        //=================== read integer from client ==========
                        InputStreamReader isr = new InputStreamReader(is);
                        BufferedReader br = new BufferedReader(isr);
                        number = br.readLine();
       //========================= set incoming file size=============================
                        mybytearray  = new byte [Integer.valueOf(number)];
        //========================read file bytes in chunks===============================         
                        bytesRead = is.read(mybytearray,0,mybytearray.length);
                        current = bytesRead;
                        do {
                           bytesRead = is.read(mybytearray, current, (mybytearray.length-current));
                           if(bytesRead >= 0) current += bytesRead;
                        } while(current < Integer.valueOf(number));
                        fos = new FileOutputStream(FILE_TO_RECEIVED);
                        bos = new BufferedOutputStream(fos);
                        bos.write(mybytearray, 0 , current);
                        bos.flush();                                
                        try{        
                            bos.close(); 
                            osw.close();
                            os.close();
              //            fos.close();
              //            bw.close();
              //            br.close();
              //            isr.close();
                            bis.close();
                            sock.close();
              //            fis.close();
                        }        
                        catch(Exception e){
                            e.printStackTrace();
                        }
                    } catch (UnknownHostException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();  
                    }  finally{
                        try{     
                        }
                        catch(Exception e){
                            e.printStackTrace();
                        }
                    } 
                }
              }).start();
            }
        });
    }       
    public static void connection(Socket s,  String serverIP, int port) {
        try {   
            Log.v(qcd, " before connecting ****...");
            s.connect(new InetSocketAddress(serverIP, port), 120000);
            Log.v(qcd, " socket connection DONE!! ");
        } catch (UnknownHostException e) {
            e.printStackTrace();
            Log.v(qcd, " Unknown host..."+e);
        } catch (IOException e) {
            e.printStackTrace();
            Log.v(qcd, " Failed to connect...   "+e);
        }
    }
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                img.setImageURI(null);
                Uri selectedImageUri = data.getData();
                selectedImagePath = getPath(selectedImageUri);
                TextView path = (TextView) findViewById(R.id.tvPath);
                path.setText("Image Path : " + selectedImagePath);
                img.setImageURI(selectedImageUri);
            }     
        }
    }
    public String getPath(Uri uri) {
        String[] projection = { MediaStore.Images.Media.DATA };
        Cursor cursor = managedQuery(uri, projection, null, null, null);
        int column_index = cursor
                .getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    } 
}

接受后将代码放入其自己的线程后,并在每次接受时启动它。

编辑:添加了螺纹代码示例:

import java.io.*;
import java.net.*;
import java.util.concurrent.atomic.AtomicInteger;
public class So43462480 {
    public interface Consumer<T> { // instead of 1.8 definition
        void accept(T t);
    }
    class Server extends Thread {
        Server(ServerSocket serverSocket,Consumer<Socket> consumer) {
            super("Server");
            this.serverSocket=serverSocket;
            this.consumer=consumer;
        }
        @Override public void run() {
            System.out.println("server running on: "+serverSocket);
            while(true)
                try {
                    Socket socket=serverSocket.accept();
                    if(consumer!=null)
                        consumer.accept(socket);
                } catch(IOException e) {
                    System.out.println(getName()+" caught: "+e);
                    break;
                }
        }
        final ServerSocket serverSocket;
        final Consumer<Socket> consumer;
    }
    void read(Socket socket) {
        InputStream inputStream=null;
        try {
            inputStream=socket.getInputStream();
            BufferedReader in=new BufferedReader(new InputStreamReader(inputStream));
            String string=in.readLine();
            System.out.println(string+" from: "+socket);
            socket.close();
            System.out.println(Thread.currentThread().getName()+" succeeded");
        } catch(IOException e) {
            System.out.println(Thread.currentThread().getName()+" caught: "+e);
        }
    }
    So43462480(String host,Integer service) throws IOException {
        ServerSocket serverSocket=new ServerSocket();
        SocketAddress socketAddress=new InetSocketAddress(host,service);
        serverSocket.bind(socketAddress);
        Consumer<Socket> socketConsumer=new Consumer<Socket>() {
            @Override public void accept(Socket socket) {
                final int n=accepts.incrementAndGet();
                System.out.println("accepted #"+n+" from: "+socket);
                new Thread(new Runnable() {
                    @Override public void run() {
                        read(socket);
                    }
                },"accept #"+n).start();
            }
        };
        new Server(serverSocket,socketConsumer).start();
    }
    static boolean send(String host,Integer service) {
        Socket socket;
        try {
            socket=new Socket(host,service);
            OutputStreamWriter out=new OutputStreamWriter(socket.getOutputStream());
            out.write("hellon");
            out.flush();
            socket.close();
            return true;
        } catch(IOException e) {
            e.printStackTrace();
        }
        return false;
    }
    public static void main(String[] args) throws InterruptedException {
        final String host="localhost";
        final Integer service=1237;
        try {
            So43462480 tcp=new So43462480(host,service);
        } catch(Exception e) {
            System.out.println("main caught: "+e);
        }
        for(int i=0;i<10;i++) {
            boolean ok=send(host,service);
            if(!ok)
                System.out.println("send failed");
        }
        Thread.sleep(100);
        for(Thread thread:Thread.getAllStackTraces().keySet())
            System.out.println(thread);
    }
    AtomicInteger accepts=new AtomicInteger();
}

编辑:一个更简单的解决方案:

import java.io.*;
import java.net.*;
import java.util.concurrent.atomic.AtomicInteger;
public class So43462480take2 {
    class Server extends Thread {
        Server(ServerSocket serverSocket) {
            super("Server");
            this.serverSocket=serverSocket;
        }
        @Override public void run() {
            System.out.println("server running on: "+serverSocket);
            while(true)
                try {
                    Socket socket=serverSocket.accept();
                    final int n=accepts.incrementAndGet();
                    System.out.println("accepted #"+n+" from: "+socket);
                    new Thread(new Runnable() {
                        @Override public void run() {
                            InputStream inputStream=null;
                            try {
                                inputStream=socket.getInputStream();
                                BufferedReader in=new BufferedReader(new InputStreamReader(inputStream));
                                String string=in.readLine();
                                System.out.println(string+" from: "+socket);
                                socket.close();
                                System.out.println(Thread.currentThread().getName()+" succeeded");
                            } catch(IOException e) {
                                System.out.println(Thread.currentThread().getName()+" caught: "+e);
                            }
                        }
                    },"accept #"+n).start();
                } catch(IOException e) {
                    System.out.println(getName()+" caught: "+e);
                    break;
                }
        }
        final ServerSocket serverSocket;
    }
    So43462480take2(String host,Integer service) throws IOException {
        serverSocket=new ServerSocket();
        SocketAddress socketAddress=new InetSocketAddress(host,service);
        serverSocket.bind(socketAddress);
        new Server(serverSocket).start();
    }
    static boolean send(String host,Integer service) {
        Socket socket;
        try {
            socket=new Socket(host,service);
            OutputStreamWriter out=new OutputStreamWriter(socket.getOutputStream());
            out.write("hellon");
            out.flush();
            socket.close();
            return true;
        } catch(IOException e) {
            e.printStackTrace();
        }
        return false;
    }
    public static void main(String[] args) throws InterruptedException, IOException {
        System.out.println("start");
        final String host="localhost";
        final Integer service=1237;
        So43462480take2 tcp=new So43462480take2(host,service);
        for(int i=0;i<10;i++) {
            boolean ok=send(host,service);
            if(!ok)
                System.out.println("send failed");
        }
        Thread.sleep(1000);
        try {
        tcp.serverSocket.close();} catch(IOException e) {
            System.out.println("close caught: "+e);
        }
        Thread.sleep(1000);
        for(Thread thread:Thread.getAllStackTraces().keySet())
            System.out.println(thread);
    }
    final ServerSocket serverSocket;
    AtomicInteger accepts=new AtomicInteger();
}

最新更新