简体   繁体   English

Java TCP Server不会将数据发送到客户端

[英]java TCP Server doesn't send data to clients

I need to make a TCP Server which accepts sockets from clients and receives data from them and send received data to all clients. 我需要制作一个TCP服务器,该服务器接受来自客户端的套接字并从它们接收数据,并将接收到的数据发送给所有客户端。 to do that my Server class saves accepted connections to an ArrayList<Socket> and while wants to send data to clients: 为此,我的Server类将接受的连接保存到ArrayList<Socket> ,并且想将数据发送到客户端:

Arraylist<Socket> sockets=Server.getSockets();
for(Socket current: sockets)
{
   ObjectOutputStream out=new ObjectOutputStream (current.getOutputStream());
   out.flush();
   out.writeObject(object);
   out.flush();
   out.close();
 }

but it doesn't work. 但这不起作用。 what's wrong? 怎么了?

There is nothing wrong with your code snippet, the only problem which I can feel is that how your client code is implemented. 您的代码段没有错,我唯一能感觉到的问题是客户端代码的实现方式。 Let us say your client code is something like this. 假设您的客户代码是这样的。

Socket clientSocket = new Socket(ip, port);
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
while ( true ){
String sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
outToServer.flush();

DataInputStream is = new DataInputStream(clientSocket.getInputStream());
System.out.println(is.readLine());
}

Now this client is reading input from console and sending it to server, post that it blocks to wait for response. 现在,此客户端正在从控制台读取输入,并将其发送到服务器,然后将其张贴以等待响应。 Lets assume server will send data to all[Which is what you want] if he receive a message 'fire' . 假设服务器收到消息“ fire”将向所有人发送数据(这是您想要的)。 Now there are two clients connected to server, ClientA and ClientB . 现在有两个连接到服务器的客户端, ClientAClientB

1. ClientA blocked at user-input (console)
2. User enter 'abc'
3. ClientA moves on sends 'abc' to server
4. ClientA blocks to read data from server
5. Server sends back 'abc' to ClientA [Assuming its an echo server]
6. ClientA reads the data, print it
7. ClientA moves back(while loop), blocked again for user input.

Same thing happen for ClientB, so now both are blocked for user input from console. ClientB也会发生相同的情况,因此现在都阻止了这两个操作,以阻止用户从控制台进行输入。
Lets say now ClientA user send our magic word ['fire' in this case], server identifies that its a magic word and start sending data to ClientA and ClientB, 假设现在ClientA用户发送了我们的魔语[在这种情况下为'fire',服务器识别出它是魔语并开始向ClientA和ClientB发送数据,

Now here the important thing to notice, which is the state of ClientA and ClientB , at this point ClientA has just send the data and is at point 4, hence is blocked to read data from server, so when server sends the message it can read and display, whereas clientB is at point 1, blocked for getting data from console.. so even though server has send data ClientB has data to read, but it can't since its stuck at point 1, also you are closing the connection from server after write, so if ClientB somehow after sometime moves from point 1 to point 4, socket is already closed, hence again it will not be able to read. 现在这里要注意的重要一点是ClientA和ClientB的状态,这时ClientA刚发送了数据,并且在第4点,因此被阻止从服务器读取数据,因此,当服务器发送消息时,它可以读取和显示,而clientB在第1点,则阻止从控制台获取数据..因此,即使服务器已发送数据,ClientB也有要读取的数据,但是由于其停留在第1点而无法读取,因此您正在从以下位置关闭连接服务器在写入后运行,因此,如果ClientB在某种程度上从点1移到点4,则套接字已经关闭,因此它将再次无法读取。 Though server has send data to both ClientA and ClientB, only ClientA is able to get it. 尽管服务器已将数据发送到ClientA和ClientB,但是只有ClientA能够获取它。

Phew!! ew! Quite a long explanation, I guess it gives you some direction to solve your problem 很长的解释,我想它为您提供解决问题的指导

Server code for reference 服务器代码供参考

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;


public class BroadCastTCPServer {

    private static ArrayList<Socket> sockets = new ArrayList<Socket>();
    //Usage: java TCPServer port
    public static void main(String args[]){

        BroadCastTCPServer server = new BroadCastTCPServer();
        try {
            server.startServer("9999");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startServer(String portStr) throws IOException {

        int port = Integer.parseInt(portStr);
        ServerSocket  serverSocket = new ServerSocket(port);

         System.out.println("Listening on IP:" +  serverSocket.getInetAddress().getHostAddress() + " Port:"+port);

         while(true){
            Socket connectionSocket = serverSocket.accept();
            sockets.add(connectionSocket);
            System.out.println("New client connection:" + connectionSocket.getRemoteSocketAddress());
            ClientHandler cl = new ClientHandler(connectionSocket);
            Thread clientThread = new Thread(cl);
            clientThread.start();
         }

    }

    public void sendAll() throws Exception{
        System.out.println("No of connections:" + sockets.size());
        for(Socket current: sockets){
            System.out.println(current.getRemoteSocketAddress());
           ObjectOutputStream out=new ObjectOutputStream (current.getOutputStream());
           out.flush();
           out.writeObject("Tata\n");
           out.flush();
           //out.close();
         }
    }

    class ClientHandler implements Runnable{

        Socket socket;
        public ClientHandler(Socket socket){
            this.socket = socket;
        }
        @Override
        public void run() {
            BufferedReader inFromClient = null;
            ObjectOutputStream out = null;
            BufferedWriter br = null;
            try {
                inFromClient = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                out=new ObjectOutputStream (socket.getOutputStream());
                OutputStreamWriter or= new OutputStreamWriter(out);
                br = new BufferedWriter(or);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            while(true){
            String clientSentence= null;
            try {
                clientSentence = inFromClient.readLine() ;
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            System.out.println("Received: " + clientSentence);
            if (clientSentence.equalsIgnoreCase("fire")) {
                try {
                    sendAll();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }else{
                try {
                    br.write(clientSentence + "\n" );
                    br.flush();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            }
        }

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM