2013-05-01 130 views
0

我正在创建这个小客户端服务器程序来了解套接字,到目前为止,我遇到了一些麻烦。为了本文的目的,我将代码整合到一个类中。代码将被编译。 (所以它会显示我得到的错误)由于关闭套接字,服务器回复客户端消息失败 - Java客户端 - 服务器示例

当客户端连接到服务器时,服务器套接字在服务器端正确地创建一个套接字。客户端然后成功地向服务器发送消息,但是当服务器尝试向客户端发送响应时,出现错误,表示套接字已关闭。

Main.java

package main; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.BindException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketException; 
import java.net.UnknownHostException; 
import java.util.Hashtable; 

public class Main { 

    boolean running = true; 

    public static void main(String[] args){ 
     new Main().start(); 
    } 

    public void start(){ 
     new Thread(new ConnectionListener()).start(); //Starts Server 
     try { 
      connectToServer(); 
     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public class ConnectionListener implements Runnable{  
     public void run() { 
      ServerSocket ss = null; 

      try { 
       ss = new ServerSocket(31415); 
      }catch (BindException e) { 
       e.printStackTrace(); 
       return; 
      } catch (IOException e) { 
       e.printStackTrace(); 
       return; 
      } 

      while(running){ 
       try { 
        Socket sock = ss.accept(); 
        ServerConnection c = new ServerConnection(sock); 
        c.start(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 

      try { 
       ss.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void connectToServer() throws UnknownHostException, IOException{ 
     //Create Connection to Server 
     Socket socket = new Socket("localhost",31415); 
     ClientConnection cc = new ClientConnection(socket); 
     cc.start(); 

     //Send First Message to Server 
     Hashtable<Integer, String> htt = new Hashtable<Integer, String>(); 
     htt.put(0,"Hello, This is a Chat Test"); 

     Message m = new Message(Message.Type.CHAT,htt); 
     cc.sendMessage(m); 
    } 

    public class ServerConnection{ 
     Socket sock; 
     boolean connected = true; 

     public ServerConnection(Socket sock){ 
      this.sock = sock; 
     } 

     public void start() { 
      new Thread(new RequestListener()).start(); 
     } 

     private void handleMessage(Message m){ 
      System.out.println("Server : Handle message " + m.type.toString()); 
     } 

     public void disconnect(){ 
      System.out.println("Disconnect user"); 
     } 

     public void sendMessage(Message m){ 
       try { 
        ObjectOutputStream os = new ObjectOutputStream(sock.getOutputStream()); 
        os.writeObject(m); 
        os.flush(); 
        os.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
     } 

     class RequestListener implements Runnable{ 

      public void run() { 

       ObjectInputStream is = null; 

       try { 
        is = new ObjectInputStream(sock.getInputStream()); 

        while(connected){ 
         try { 
          Message m = (Message) 
            is.readObject(); //EOFException 
          handleMessage(m); 
         } catch (ClassNotFoundException e) { 
          e.printStackTrace(); 
         }catch(SocketException e){ 
          disconnect(); 
          e.printStackTrace(); 
          break; 

         }catch (IOException e) { 
          //e.printStackTrace(); //EOFException Here 
         } 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       }finally{ 
        try { 
         is.close(); 

        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 

    public class ClientConnection { 

     private Socket socket; 
     private boolean connected = true; 

     public ClientConnection(Socket socket) { 
      this.socket = socket; 
     } 

     public void start(){ 
      new Thread(new RequestListener()).start(); 
     } 

     public void sendMessage(Message m){ 
      try { 
       ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream()); 
       os.writeObject(m); 
       os.flush(); 
       os.close(); 
      } catch (IOException e) { 
       System.out.println("Error Sending Message"); 
       e.printStackTrace(); 
      } 
     } 

     public void close() throws IOException{ 
      Message m = new Message(Message.Type.DISCONNECT,null); 
      sendMessage(m); 
      socket.close(); 
     } 

     private void handleMessage(Message m){ 
      System.out.println("Client : Handle message " + m.type.toString()); 
     } 

     class RequestListener implements Runnable{ 

      public void run() { 

       ObjectInputStream is = null; 

       try { 

        System.out.println(socket.isConnected()); //true 
        System.out.println(socket.isClosed()); //false 
        InputStream iss = socket.getInputStream(); 
        is = new ObjectInputStream(iss); //socketClosedException 

        while(connected){ 
         try { 
          Message m = (Message)is.readObject(); 
          handleMessage(m); 
         } catch (ClassNotFoundException e) { 
          e.printStackTrace(); 
         }catch(SocketException e){ 

          System.out.println("Server Disconnected"); 
          break; 

         }catch (IOException e) { 
          e.printStackTrace(); 
         } 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       }finally{ 
        try { 
         is.close(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    } 
} 

Message.java

package main; 

import java.io.Serializable; 
import java.util.Hashtable; 

public class Message implements Serializable{ 

    public enum Type{ 
     LOGIN, PM, DISCONNECT, INCORRECT_LP,CORRECT_LP, UPDATE_USERLIST, CHAT, INCORRECT_VERSION 
    } 

    public Type type; 
    Hashtable ht; 

    public Message(Type type, Hashtable ht){ 
     this.type = type; 
     this.ht = ht; 
    } 

    public Object get(Object o){ 
     return ht.get(o); 
    } 
} 
+1

也许我错过了这里的东西,但它看起来像我发送消息,然后关闭客户端中的套接字。 – 2013-05-01 01:39:18

+0

我认为理查德是对的。注释你的主类的第166行的'os.close()',你不会得到错误。 – Faraway 2013-05-01 02:11:42

回答

1

没有什么 '随机' 了。

关闭一个Socket的输入或输出流关闭其他流和Socket.

在这种情况下会关闭ObjectOutputStream已套接字输出流,其关闭该输出物流,其关闭所述缠套接字的输入流和套接字。

相关问题