Tôi đang lập trình một lớp để giao tiếp với máy chủ nhưng khi nó cố gắng xây dựng ObjectInputStream với sự trợ giúp của luồng đầu vào chương trình bị đóng băng. Theres không có ngoại lệ và chương trình vẫn chạy nhưng treo trong dòng nơi nó cố gắng xây dựng ObjectInputstream.ObjectInputStream (socket.getInputStream()); không hoạt động
Heres mã của phương pháp mà vấn đề của tôi tọa lạc:
@Override
public void connect(String ip, int port) throws UnknownHostException, IOException {
Socket socket = new Socket(ip, port);
out = new ObjectOutputStream(socket.getOutputStream());
InputStream is = socket.getInputStream();
in = new ObjectInputStream(is);
}
và đây là mã cho cả lớp:
package Client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MessageStreamerImpl implements MessageStreamer {
ObjectOutputStream out;
ObjectInputStream in;
public MessageStreamerImpl(String ip, int port) throws UnknownHostException, IOException{
connect(ip, port);
}
public MessageStreamerImpl(){
}
@Override
public void send(Object message) throws IOException {
if(out == null) throw new IOException();
out.writeObject(message);
out.flush();
}
@Override
public Object receive() throws IOException{
try {
return in.readObject();
} catch (ClassNotFoundException e) {
throw new IOException();
}
}
@Override
public void connect(String ip, int port) throws UnknownHostException, IOException {
Socket socket = new Socket(ip, port);
out = new ObjectOutputStream(socket.getOutputStream());
InputStream is = socket.getInputStream();
in = new ObjectInputStream(is);
}
}
Trong khi tìm kiếm tại Google Tôi thấy điều này: http://www.coderanch.com/t/232944/threads/java/Socket-getInputStream-block. Nhưng tôi vẫn không biết làm thế nào để giải quyết vấn đề, bởi vì constructor ObjectOutputStream của tôi là trước một cho ObjectInputStream.
Đây là mã máy chủ của tôi, có lẽ nó sẽ giúp;)
package Server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
public class Server {
ArrayList<Socket> clients = new ArrayList<Socket>();
public Server(int port){
try {
ServerSocket mySocket = new ServerSocket(port);
waitForClients(mySocket);
} catch (IOException e) {
System.out.println("Unable to start.");
e.printStackTrace();
}
}
private void waitForClients(ServerSocket mySocket) {
while(true){
try {
System.out.println("Ready to receive");
Socket client = mySocket.accept();
clients.add(client);
System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server");
Thread t = new Thread(new ClientHandler(client));
t.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void shareToAll(Object objectToSchare){
for(Socket client:clients){
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(objectToSchare);
oos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class ClientHandler implements Runnable{
Socket clientSocket;
public ClientHandler(Socket clientSocket){
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
while(true){
try {
ois.readObject();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}catch(SocketException e){
System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server");
clients.remove(clientSocket);
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Nhờ sự giúp đỡ của bạn tôi thấy lỗi. Đó là tại lớp máy chủ trong đó có xem xét như thế này:
package Server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
public class Server {
ArrayList<ObjectOutputStream> clientstreams = new ArrayList<ObjectOutputStream>();
public Server(int port){
try {
ServerSocket mySocket = new ServerSocket(port);
waitForClients(mySocket);
} catch (IOException e) {
System.out.println("Unable to start.");
e.printStackTrace();
}
}
private void waitForClients(ServerSocket mySocket) {
while(true){
try {
System.out.println("Ready to receive");
Socket client = mySocket.accept();
clientstreams.add(new ObjectOutputStream(client.getOutputStream()));
System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server");
Thread t = new Thread(new ClientHandler(client));
t.start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void shareToAll(Object objectToSchare){
for(ObjectOutputStream stream:clientstreams){
try {
stream.writeObject(objectToSchare);
stream.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class ClientHandler implements Runnable{
Socket clientSocket;
public ClientHandler(Socket clientSocket){
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
while(true){
try {
ois.readObject();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}catch(SocketException e){
System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server");
clientstreams.remove(clientSocket);
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Phần lớn thay đổi mà bạn nhìn thấy ở waitForClients() phương pháp nhưng tôi đã thay đổi, quá khái niệm về ArrayList của tôi và phương pháp shareToAll.
Tôi không biết bạn có giống nhau hay không nhưng tôi đã tìm ra lý do. Các faul là trong lớp máy chủ tại phương thức waitForClients() Tôi phải tạo ra một Outputstream sau khi Socket client = mySocket.accept(); với client.getOutputstream() ;. Nếu không, Máy khách bị chặn chờ OutputStream (InputStream của anh ta). Cảm ơn bạn –
Tôi đã chỉnh sửa câu hỏi vì tôi chưa được phép trả lời câu hỏi của riêng tôi. –
bạn vẫn không nên xác định lại luồng đầu vào và đầu ra mỗi lần. Chúng phải là toàn cục bên trong lớp 'ClientHandler'. – Jon