我需要创建一个TCP服务器,它接受来自客户端的套接字并从中接收数据并将接收的数据发送给所有客户端。要做到这一点,我的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();
}
但它不起作用。怎么了?
答案 0 :(得分:1)
您的代码段没有任何问题,我能感受到的唯一问题是您的客户端代码是如何实现的。我们假设您的客户端代码是这样的。
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());
}
现在这个客户端正在从控制台读取输入并将其发送到服务器,发布它阻止等待响应。让我们假设服务器会在收到消息'fire'时向所有人发送数据[这就是你想要的]。
现在有两个客户端连接到服务器, ClientA 和 ClientB 。
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.
同样的事情发生在ClientB上,所以现在两者都被阻止来自控制台的用户输入
让我们说现在ClientA用户发送我们的神奇字[在这种情况下''火'],服务器识别它是一个神奇的词并开始向ClientA和ClientB发送数据,
现在需要注意的重要事项,即ClientA和ClientB的状态,此时ClientA刚刚发送数据并且位于第4点,因此被阻止从服务器读取数据,所以当服务器发送它可以读取和显示的消息,而clientB在第1点,被阻止从控制台获取数据..所以即使服务器发送数据,ClientB也有数据要读取,但它不能因为它卡在第1点,你也是在写入后关闭服务器的连接,所以如果ClientB以某种方式从某一点移动到第4点,那么套接字已经关闭,因此它将再次无法读取。虽然服务器已向ClientA和ClientB发送数据,但只有ClientA能够获取它。
唷!!相当长的解释,我想它会给你一些方向来解决你的问题
供参考的服务器代码
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();
}
}
}
}
}
}