2014-12-06 34 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 

您应该为每个连接创建一个阅读器,并在循环中重新使用它。