2014-12-06 55 views
-1

對於我的Software Engineering類,我的組必須從服務器獲取相機流並通過套接字將其發送到客戶端。我們通過不斷地通過套接字發送圖像來做到這一點當我們嘗試運行我們的程序時,我們只能得到一個圖像,但下一個圖像變爲空,因此我們得到一個空指針異常。緩衝區IO上的空指針異常

這裏是UserClient類。 UserClient接收一系列圖像。空指針出現在run方法中,我用註釋標記它。

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package communication; 

import java.awt.image.BufferedImage; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.ObjectInputStream; 
import java.net.ConnectException; 
import java.net.Socket; 
import java.net.UnknownHostException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 

import javax.swing.JOptionPane; 
import userpc.RoverGUI; 

/** 
* A simple Swing-based client for the capitalization server. It has a main 
* frame window with a text field for entering strings and a textarea to see the 
* results of capitalizing them. 
*/ 
public class UserClient extends Thread{ 

    //ObjectInputStream input; 
    Socket s = null; 
    boolean done = false; 
    String serverAddress; 
    RoverGUI gui; 

    public static void main(String[] args){ 
     String serverAddress = JOptionPane.showInputDialog(
       "Enter IP Address of a machine that is\n" 
       + "running the date service on port 9090:"); 
     try { 
      UserClient c = new UserClient(null, serverAddress); 
     } catch (IOException ex) { 
      Logger.getLogger(UserClient.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    public UserClient(RoverGUI gui, String serverAddress) throws UnknownHostException, IOException{ 
     this.gui=gui; 
     this.serverAddress=serverAddress; 
    } 

    @Override 
    public void run(){ 
     while (!done) { 
      try { 
       if (serverAddress.equals("")) { 
        throw new UnknownHostException(); 
       } 
       s = new Socket(serverAddress, 9090); 
       //input =new ObjectInputStream(s.getInputStream()); 
       done = true; 
      } catch (ConnectException e) { 
       gui.display("Wait for servor..."); 
      } catch (UnknownHostException ex) { 
       gui.display("Un known Host Exception Occur..."); 
      } catch (IOException ex) { 
       Logger.getLogger(UserClient.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 

     while(true){ 
      try { 
        gui.setIcons(ImageIO.read(ImageIO.createImageInputStream(s.getInputStream())),null); 
//NULL POINTER HERE 
       //System.out.println(input.readLine()); 
      } catch (IOException ex) { 
       Logger.getLogger(UserClient.class.getName()).log(Level.SEVERE, null, ex); 
      } 
     } 
    } 

    public void close() throws IOException { 
     //input.close(); 
     s.close(); 
    } 
} 

RoverServer發送圖像流。

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package communication; 

import camera.ImageBuffer; 
import java.io.IOException; 
import java.io.ObjectOutputStream; 
import java.io.PrintWriter; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

/** 
* 
* @author junxin 
*/ 
public class RoverServer implements Runnable { 

    Socket socket = null; 
    ServerSocket listener = null; 
    ObjectOutputStream out; 
    ImageBuffer ib; 
    RoverClient client; 

    public static void main(String arg[]){ 
     try { 
      ImageBuffer ib=new ImageBuffer(); 
      RoverServer server=new RoverServer(ib); 
      new Thread(server).start(); 
      RoverClient client= new RoverClient("150.250.220.214"); 
      client.start(); 
     } catch (IOException ex) { 
      Logger.getLogger(RoverServer.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    public RoverServer(ImageBuffer ib) { 
     this.ib=ib; 
     try { 
      listener = new ServerSocket(9090); 
     } catch (IOException ex) { 
      Logger.getLogger(RoverServer.class.getName()).log(Level.SEVERE, null, ex); 
     } 

    } 

    @Override 
    public void run() { 
     try { 
      socket = listener.accept(); 
      System.out.println("Client accept"); 

      out =new ObjectOutputStream(socket.getOutputStream()); 
      while(true){ 
       //out.printf("", ib.getImage(),ib.getImage2()); 
       out.writeObject(ib.getImage()); 
       Thread.sleep(100); 
      } 
     } catch (IOException ex) { 
      System.out.println("Unable to accept client!"); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(RoverServer.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

感謝您的幫助!

+1

ib.getImage()如何工作?順便說一句,你需要實現一種方式來等待來自服務器的圖像。你的服務器正在休眠100ms,但你的客戶端總是試圖讀取輸入流......當沒有數據被髮送時它是空的...... – Ubica 2014-12-06 05:58:00

+0

你是否看到任何字符串,如「等待servor ...」 「記錄器中的」logger.getLogger(UserClient.class.getName())。log(Level.SEVERE,null,ex);「 – SMA 2014-12-06 06:08:41

+0

當服務器沒有發送數據時,我不認爲輸入流爲空。我沒有eclipse/jdk,但我認爲在這種情況下,輸入流會阻塞並獲得0。 – Michal 2014-12-06 07:28:02

回答

0
gui.setIcons(ImageIO.read(ImageIO.createImageInputStream(s.getInputStream())),null); 

將套接字輸入流分配給一個新的閱讀器,對吧?
每個流僅允許一次。
此外,如果你指定流多的讀者,只有第一個讀者可以從流
在folling例如讀取,只有第一個讀者得到的值(服務器發送喜\ NAT \ n所有):

 BufferedReader firstReader = new BufferedReader(new InputStreamReader(
       socket.getInputStream())); 
     BufferedReader secondReader = new BufferedReader(new InputStreamReader(
       socket.getInputStream())); 
     System.out.println("str = " + firstReader.readLine()); //str = hi 
     System.out.println("str = " + secondReader.readLine()); //str = null !!!!! 
     System.out.println("str = " + firstReader.readLine()); //str = at 
     System.out.println("str = " + firstReader.readLine()); //str = all 

您應該爲每個連接創建一個閱讀器,並在循環中重新使用它。