2014-04-27 2 views
0

해결할 수없는 간단한 수정 프로그램이어야합니다. 서버와 클라이언트 사이의 총 계산, 가격 * 수량을 반환합니다. 그러나 java.net.SocketException: Connection Reset을 받고 있습니다. ComputerServer 클래스 (클래스 HandleAClient, ComputerClient 클래스 및 Computer 클래스)를 삽입했습니다. 나는 어떤 도움도 환영한다. 고맙습니다!멀티 스레딩 클라이언트/서버, 소켓 예외

import java.io.*; 
import java.util.*; 
import java.net.*; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ExecutorService; 

public class ComputerServer 
{ 
    public static void main(String args[]) 
    { 
     ServerSocket serverSocket; 
     Socket connection; 

     ObjectInputStream input; 
     ObjectOutputStream output; 

     Computer c = null; 

     Object obj; 

     double totalCharge; 

     try 
     { 
      serverSocket = new ServerSocket(8000); 
      System.out.println("Waiting for Client"); 

      int clientNo = 1; 

      ExecutorService threadExecutor = Executors.newCachedThreadPool(); 

      while(true)//runs indefinitely 
      { 
       connection = serverSocket.accept(); 

       input = new ObjectInputStream(connection.getInputStream()); 
       output = new ObjectOutputStream(connection.getOutputStream()); 

       obj = input.readObject(); 

       System.out.println("Object Received from client:\n"+obj); 

       if(obj instanceof Computer) 
       { 
        totalCharge = ((Computer)obj).getPrice()*((Computer)obj).getQuantity(); 

        HandleAClient thread = new HandleAClient(connection, clientNo, totalCharge); 

        threadExecutor.execute(thread); 

        output.writeObject(totalCharge); 
        output.flush(); 
       } 





       clientNo++; 
      } 

     } 
     catch(ClassNotFoundException cnfe) 
     { 
      cnfe.printStackTrace(); 
     } 
     catch(IOException ioe) 
     { 
      ioe.printStackTrace(); 
     } 

    }//end of main 
} 

class HandleAClient implements Runnable 
{ 
    //**SHOULD i do object... 
    //Scanner input; 
    //Formatter output; 
    Object obj; 

    ObjectOutputStream output; 
    ObjectInputStream input; 

    Socket connection; 
    ServerSocket serverSocket; 

    int clientNo; 

    //variables for calculation 
    //variables for calculation 
    double price; 
    double totalCharge; 


    public HandleAClient(Socket connection, int clientNo, double totalCharge) 
    { 
     this.connection = connection; 
     this.clientNo = clientNo; 
     this.totalCharge = totalCharge; 
    } 

    public void run() 
    { 
     //ArrayList<Computer> cList = new ArrayList<Computer>(); 

     try 
     { 


      input = new ObjectInputStream(connection.getInputStream()); 
      output = new ObjectOutputStream(connection.getOutputStream()); 


      /*while(input.hasNext()) 
      { 
       //variable = input.next.... 
       //print out calculation 
       price = input.nextDouble(); 
       System.out.println("Price received from client:\t"+clientNo+"is"+price); 

       //DO CALCULATION, STORE IT 

       for(Computer c: cList)//**TRYING a for loop 
       { 
        totalCharge = ((Computer)c).getPrice() * ((Computer)c).getQuantity(); 

        output.format("%.2f\n", totalCharge); 

        //output.flush(); 
       } 
      //}*/ 

      System.out.println("TotalCharge"+totalCharge); 
      System.out.println("Thread"+"\t"+clientNo+"\t"+"ended"); 
     } 
     catch(IOException ioe) 
     { 
      ioe.printStackTrace(); 
     } 
    } 
} 

    import java.util.*; 
import java.io.*; 
import java.net.*; 

public class ComputerClient 
{ 
    public static void main(String args[]) 
    { 
     Socket connection; 

     ObjectOutputStream output; 
     ObjectInputStream input; 

     Object obj; 

     Computer c = new Computer("Asus",1189.99,4); 

     try 
     { 
      connection = new Socket("localhost",8000); 

      output = new ObjectOutputStream(connection.getOutputStream()); 
      input = new ObjectInputStream(connection.getInputStream()); 

      output.writeObject(c); 
      output.flush(); 

      //read back: 

      obj=(Object)input.readObject(); 

      System.out.println(obj.toString()); 
     } 
     catch(ClassNotFoundException cnfe) 
     { 
      cnfe.printStackTrace(); 
     } 
     catch(IOException ioe) 
     { 
      ioe.printStackTrace(); 
     } 
    } 
} 
    import java.io.Serializable; 

public class Computer implements Serializable 
{ 
    private String brand; 
    private double price; 
    private int quantity; 

    public Computer() 
    { 
     setBrand(""); 
     setPrice(0.0); 
     setQuantity(0); 
    } 

    public Computer(String b, double p, int q) 
    { 
     setBrand(b); 
     setPrice(p); 
     setQuantity(q); 
    } 

    public String getBrand() 
    { 
     return brand; 
    } 

    public double getPrice() 
    { 
     return price; 
    } 

    public int getQuantity() 
    { 
     return quantity; 
    } 

    public void setBrand(String b) 
    { 
     brand = b; 
    } 

    public void setPrice(double p) 
    { 
     price = p; 
    } 

    public void setQuantity(int q) 
    { 
     quantity = q; 
    } 

    public String toString() 
    { 
     return("Brand: "+brand+"\t"+"Price: "+price+"\t"+"Quantity: "+quantity); 
    } 
} 
+0

방금 ​​출력 한 결과 4759.96이 출력되었습니다. 예외는 전혀 없습니다. 게시물에 스택 추적을 추가 할 수 있습니까? – Don

+0

실행 해 주셔서 감사합니다. 예외는 클라이언트가 아닌 서버에서 버려집니다. 나는 할 것이다. – Alfred

+0

내 서버 창이 이클립스에 의해 클라이언트 윈도우 아래에 묻혀서 나쁘다. 나는 지금 그것을보고 대답을 게시했다. – Don

답변

0

'연결 재설정'은 일반적으로 피어에 의해 이미 닫힌 연결에 작성했음을 의미합니다. 즉, 응용 프로그램 프로토콜 오류입니다. 동료가 읽지 않은 것을 작성했습니다. 다음 I/O 작업 또는 버퍼링에 따라 후속 I/O 작업은 '연결 재설정'을 가져옵니다.

이 경우 서버는 totalCharge을 쓰고 두 개의 ObjectOutputStreams을 초기화합니다.이 둘은 스트림에 헤더를 씁니다. 클라이언트는 하나의 헤더를 읽고 하나의 객체를 읽은 다음 연결을 닫는 하나의 ObjectInputStream, 만 생성합니다. 따라서 다른 헤더는 아무 곳에도 기록되지 않고 예외가 발생합니다.

이 작업을 수행 할 수 없습니다. 동일한 소켓에 여러 개의 ObjectOutputStreams을 사용할 수 없습니다. 최소한 여기서는 분명하지 않습니다. 또한 accept 루프에서 I/O를 수행하지 않아야합니다. 모든 클라이언트 프로세싱을 HandleAClient 클래스로 옮긴다. 이것은 결국 무엇을위한 것이며, accept와 connect를 제외하고 accept 루프에서 아무것도하지 않는다.

또한 서버와 클라이언트가 연결을 닫지 않습니다. 서버가 소켓을 누설하고 클라이언트가 종료됩니다. 운영 체제가 클라이언트의 경우에 당신을 위해 그것을 닫고 있지만 그것은 좋지 않습니다. 연결을 닫으십시오. 이 경우에는 닫아야합니다. ObjectOutputStream.

-1

답변 후에 코드가 수정 된 것처럼 보이지 않습니다.

+0

지금까지는 클래스에서 ServerSocket serverSocket으로 초기화되었습니다. 그러나, 새로운 ServerSocket (// 포트)을 설정한다고 조언하고 있습니까? 서버를 실행중인 포트와 동일한 포트로 설정하면 바인딩이 해제됩니다. 다시 한 번 감사드립니다! – Alfred

+0

아니요, 여기에 게시 된 버전에서 해당 호출에서 null 포인터 예외가 발생합니다. 따라서 serverSocket이 해당 단계에서 초기화 될 것으로 예상되는 경우 null 포인터 예외가 발생하므로 초기화되지 않았습니다. 만약 내가 그 코드를 여기에 게시 된 당신이 테스트하는 버전과 꽤 같지 않은 연결 재설정 예외를 얻을 전화를 언급. 원래 응답 할 때마다 편집 한 것을 볼 수 있으므로 다시 설정 예외가 표시됩니다. – Don

+0

@Alfred 초기화가 아니라 선언입니다. 'HandleAClient'에'ServerSocket'이 전혀 필요 없습니다. – EJP

관련 문제