2013-12-12 159 views
0

我设法设置了一个服务器,它将接受管理多个套接字客户端的&。 但现在当我尝试发送消息时,服务器只是不会收到任何东西,但我会刷新消息。Java多客户端服务器不接收来自客户端的消息?

此处所说的管理客户端的方法:

public void run() { 

    while(true) { 
     for (Client c : this.clients) { 
      try { 
       if (c.getStream().read() != -1) { 
        if (c.getInputStream() != null) { 
         System.out.println("He sent message"); 
         c.sendMessage("hey client"); 
        } 
       } 
      } catch (IOException e) { 
       c.destruct(); 
       this.clients.remove(c); break; 
      } 
     } 

     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

客户名单:

public ArrayList<Client> clients = new ArrayList<Client>(); // client list 

和客户对象:

public class Client { 

    private Socket socket; 
    private int clientId; 
    private BufferedReader inStream; 
    private PrintWriter outStream; 
    private boolean socketAlive = true; 

    public Client(Socket sock) { 
     this.socket = sock; 
    } 

    public void setup() { 
     setInputOutputStream(); 
     System.out.println("New connection: " + this.getIpAddress()); 
     this.sendMessage("Successfully connected!"); 
    } 

    public BufferedReader getStream() { 
     return this.inStream; 
    } 

    public String getInputStream() { 
     String toReturn = ""; 
     try { 
      toReturn = this.inStream.readLine(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return toReturn; 
    } 

    public void destruct() { 
     try { 
      this.inStream.close(); 
      this.inStream = null; 
      this.outStream.close(); 
      this.outStream = null; 
      System.out.println("Client destruct: " + this.socket.getLocalSocketAddress()); 
      this.socket.close(); 
      this.socket = null; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public Socket getConnection() { 
     return this.socket; 
    } 

    private void setInputOutputStream() { 
     try { 
      inStream = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); 
      outStream = new PrintWriter(this.socket.getOutputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void sendMessage(String s) { 
     this.outStream.println(s); 
     this.outStream.flush(); 
    } 

    public String getIpAddress() { 
     return this.socket.getRemoteSocketAddress().toString(); 
    } 
} 

和客户端(发送方):

public static void main(String[] args) { 
    try { 
     System.out.println("Client started"); 
     Socket sock = new Socket("localhost", 43594); 
     Scanner scanner = new Scanner(System.in); 
     String input; 
     PrintWriter out = new PrintWriter(sock.getOutputStream()); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream())); 

     while (true) { 
      input = scanner.nextLine(); 

      if (input != null) { 
       out.print(input); 
       out.flush(); 
      } 
     } 
    } catch (IOException e) { 
     System.out.println("Client error"); 
    } 

} 

为什么我的服务器没有收到任何东西?

一件事:

如果我发短信+断开,这个服务器将记录的内容(它看起来只是一旦断开或东西发送消息,以及不,它只是在它进入if块) :

Server is successfully running on port 43594 
New connection: /127.0.0.1:57102 
He sent message 
java.net.SocketException: Connection reset 
    at java.net.SocketInputStream.read(Unknown Source) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at sun.nio.cs.StreamDecoder.readBytes(Unknown Source) 
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source) 
    at sun.nio.cs.StreamDecoder.read(Unknown Source) 
    at java.io.InputStreamReader.read(Unknown Source) 
    at java.io.BufferedReader.fill(Unknown Source) 
    at java.io.BufferedReader.readLine(Unknown Source) 
    at java.io.BufferedReader.readLine(Unknown Source) 
    at Client.getInputStream(Client.java:32) 
    at ClientHandler.run(ClientHandler.java:21) 
Client destruct: 0.0.0.0/0.0.0.0:43594 

我做错了什么?我怎样才能解决这个问题

服务器(主类)

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.*; 
import java.util.ArrayList; 

public class Server { 

    private int port = 43594; 

    public void listen() { 
     System.out.println("Trying to listen..."); 
     try { 
      final ServerSocket server = new ServerSocket(port); 
      // Create new thread to handle clients I/O 
      ClientHandler handler = new ClientHandler(server); 
      // START it 
      handler.start(); 
      System.out.println("Server is successfully running on port " + port); 
      while (true) { 
       // New connection found create a new Client object 
       Client cl = new Client(server.accept()); 
       cl.setup(); 
       // add it to clietns list in the I/O handler 
       handler.clients.add(cl); 
      }   
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    public static void main(String[] args) { 
     // start up 
     System.out.println("Starting up.."); 

     // server instance 
     final Server server = new Server(); 

     // create a new thread for server 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       // listen for new connections 
       server.listen(); 
      } 
     }).start(); 
    } 
} 
+0

你为什么让服务器发送消息给客户端?为了建立一个消息服务器系统,你真的想拥有诸如多线程(所以两个并排线程)服务器和客户端之类的东西,然后在收到消息时使用回调进行更新。我对你的逻辑有些困惑。你的服务器和客户端是两个独立的程序吗?等等请多解释一下你的设置和问题。 –

+0

@EthanBrouwer是的这些是两个分离的程序,我已经添加了服务器的主类,进行了编辑。 –

+0

不过,'c.sendMessage(“hey client”);'。你为什么这样做? 'c'是对arraylist中你的一个客户的引用,所以服务器不应该为它发送消息。我认为你有你的客户和你的服务器搞砸了。 –

回答

0

我认为问题来自于一个事实,你有客户名单,并试图与管理它们。我抬头java.net.SocketException: Connection reset,发现这样一个问题:What's causing my java.net.SocketException: Connection reset?

回答这个问题来了这一点:

你的情况看来,连接已经被连接的 服务器端关闭。这可能是您要发送的请求 或其结尾处的问题的问题。

这让我觉得你没有每次都与客户端保持连接。你存储它,然后你失去它,所以消息不会被发送。要处理更多的客户端,您可能更希望拥有一个IP列表,而不是客户端,然后在您想要发送消息时进行连接。您不能存储Socket连接。它必须积极。 Java(The JVM)有它自己的“垃圾收集”系统,它会杀死它。

1

客户端正在发送数据,服务器正在读取。

我认为这个问题是在Client.getInputStream

this.inStream.readLine(),它读取一行文本。 来自文档: “读取一行文本。行被认为由换行符('\ n'),回车符('\ r')或回车符后面的任意一个终止换行。“

http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html

如果您使用读相反,也许是去工作。只需使用一种协议的如发送第1或2个字节的消息的长度。或者你可以发送一个“\ n'客户端

顺便说一句,在客户端发送和断开连接时,服务器发生异常的原因可能是TCP事实。客户端关闭了连接,它可能收到TCP ACK然后客户端发送一个RESET段,但不太确定,服务器在this.inStream.readLine(),然后它收到一个异常,你是不是也收到了“由对等关闭的连接?”

1

我不知道为什么,但我需要使用out.println(input) out.flush()而不是.print().write()

我没有的,为什么我需要做的解释。但它的工作。

+1

这是因为你必须添加一个\ n,因为我在我的回复中解释过你 – rodolk

+0

哦......我看到.... –

相关问题