【发布时间】:2019-12-08 17:21:25
【问题描述】:
我正在开发一个客户端-服务器应用程序,我的服务器可以接收来自 2 种类型客户端的连接请求,因此我直接在我的服务器中实例化 ObjectInputStream,以识别客户端类型(客户端或工作者)然后我有每种类型的客户端都有一个线程。
在初始化线程时,我将在服务器中创建的套接字作为参数传递。 (代码如下)
public class Server {
public int PORT;
private ArrayList<DealWithClient> connectedClients;
private ArrayList<DealWithWorker> connectedWorkers;
private ArrayList<String> types = new ArrayList<>();
private BlockingQueue<Runnable> tasks = new BlockingQueue<>();
private SearchTypes searchTypes;
private ObjectOutputStream out;
private ObjectInputStream in;
public static void main(String[] args) {
new Server(args[0]);
}
public Server(String port) {
this.PORT = Integer.parseInt(port);
startServing();
}
public void startServing() {
connectedClients = new ArrayList<>();
connectedWorkers = new ArrayList<>();
try {
ServerSocket s = new ServerSocket(PORT);
System.out.println("Lançou ServerSocket: " + s);
try {
while (true) {
Socket socket = s.accept();
inscription(socket);
}
} finally {
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void inscription(Socket socket) {
try {
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
Object obj = in.readObject();
if(obj instanceof String) {
String inscriptionMessage = (String) obj;
System.out.println("Mensagem recebida: " + obj);
if(inscriptionMessage.contains("Inscrição cliente")) {
DealWithClient dwc = new DealWithClient(socket, this);
dwc.start();
addClient(dwc);
out.writeObject(searchTypes);
}
if(inscriptionMessage.contains("Inscrição worker")) {
String[] worker = inscriptionMessage.split(" ");
searchTypes = new SearchTypes(worker[4]);
DealWithWorker dww = new DealWithWorker(socket, this);
dww.start();
addWorker(dww);
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public void addClient(DealWithClient client) {
connectedClients.add(client);
System.out.println("Cliente adicionado! »» " + client.toString());
}
public void addWorker(DealWithWorker worker) {
connectedWorkers.add(worker);
System.out.println("Worker adicionado! »» " + worker.toString());
}
下面的 DealWithClient 代码是我遇到问题的地方,因为我无法访问 System.out.println("BBB"),因为它卡在 ObjectInputStream 的实例化中。
public class DealWithClient extends Thread{
private Socket socket;
private Server server;
private ObjectInputStream in;
private ObjectOutputStream out;
private Client client;
public DealWithClient(Socket socket, Server server) {
this.server = server;
this.socket = socket;
}
@Override
public void run() {
try {
connectToServer();
} catch (IOException e) {
e.printStackTrace();
}
while(!interrupted()) {
treatClientRequests();
}
}
private void connectToServer() throws IOException {
out = new ObjectOutputStream(socket.getOutputStream());
System.out.println("AAA");
in = new ObjectInputStream(socket.getInputStream());
System.out.println("BBB");
}
我在这里寻找过类似的问题,但我没有找到一个可以解决我的问题的问题。 我的问题是,一旦我在服务器中实例化了 ObjectInput 和 ObjectOutput 流,我就不能在我的 Thread 中再次执行此操作了吗?
谢谢!
【问题讨论】: