客户端 - 服务器双向通信

时间:2015-12-21 22:40:08

标签: java sockets client-server serversocket

我写了一个简单的客户端服务器,但不幸的是,我做得那么混乱而且很差,所以我决定从头开始写一切。我想写两个方向进行通信,能够断开连接并连接新客户端。这意味着客户端或服务器发送消息,并且适当的消息将读取它。在开始时所有工作,但当我想关闭客户端时,我得到两个错误:

java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closedwriteData(String data)

当然我理解这些错误意味着什么,但我不明白为什么它们出现,因为我有一个while循环,我检查客户端是否连接。后来,当我尝试连接一个新客户端时,一切都在崩溃。 我写了3个类客户端,服务器和通信。客户端和服务器继承自通信(打开和读取数据流的方法)。这一切看起来都是这样的:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class Server extends Communication{

ServerSocket serverSocket;
Socket listener;
boolean listenerLife;

public Server(int port) {

    try {
        serverSocket = new ServerSocket(port);
    } catch (IOException e) {
        System.out.println(e);
    }
}

public void startListener(){

    while (true){
        try {
            listener = serverSocket.accept();
            listenerLife = true;
        } catch (IOException e) {
            System.out.println(e);
        }
        openWriter(listener);
        openReader(listener);
        writeServerDataThread();
        new Thread(new Runnable() {
            @Override
            public void run() {
                readData();
            }
        }).start();
    }

}

public void writeServerDataThread(){
    openLocalReader();
    new Thread(new Runnable() {
        @Override
        public void run() {
            while (true){
                String data = readLocalData();
                writeData(data);
            }
        }
    }).start();
}


public void readData(){
    while (listenerLife){
        String data = readSocketData();

        if("exit".equals(data) || data == null){
            try {
                listenerLife = false;
                listener.close();
            } catch (IOException e) {
                System.out.println(e);
            }
        }
        else {
            System.out.println(data);
        }

    }
}



public void writeData(String data){
    try {
        writer.writeBytes(data + '\n');
        writer.flush();
    } catch (IOException e) {
        System.out.println(e);
    }
}



public static void main(String[] args) {
    Server server = new Server(8080);

    server.startListener();


}
}
import java.io.IOException;
import java.net.Socket;

public class Client extends Communication{

Socket clientSocket;
boolean clientLive;

public Client(String hostName, int port) {

    try {
        clientSocket = new Socket(hostName, port);
        clientLive = true;
    } catch (IOException e) {
        System.out.println(e + "Client(String hostName, int port)");
    }

}

public boolean closeConnection(String data){
    if("exit".equals(data) || data == null){
        try {
            writeData("Zamykam klienta");
            clientSocket.close();
            clientLive = false;
            return false;
        } catch (IOException e) {
            System.out.println(e + "closeConnection(String data)");
        }
    }
    return true;
}

public void readClientData(){
    new Thread(new Runnable() {
        @Override
        public synchronized void run() {
            openLocalReader();
            while (!clientSocket.isClosed()){
                String data = readLocalData();

                if(closeConnection(data)){
                    writeData(data);
                }
            }
        }
    }).start();

}

public void readServerDataThread(){
    new Thread(new Runnable() {
        @Override
        public synchronized void run() {
            while (!clientSocket.isClosed()){
                String data = readSocketData();

                if(closeConnection(data)){
                    System.out.println(data);
                }
            }
        }
    }).start();

}

public void writeData(String data){
    try {
        writer.writeBytes(data + '\n');
        writer.flush();
    } catch (IOException e) {
        System.out.println(e + "writeData(String data)");
    }
}

public static void main(String[] args) {
    final Client client = new Client("localhost", 8080);
    client.openReader(client.clientSocket);
    client.openWriter(client.clientSocket);
    client.readServerDataThread();

    client.readClientData();


}
}
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

public class Communication {

BufferedReader reader;
BufferedReader localReader;
DataOutputStream writer;

public void openReader(Socket incomingSocket){

    try {
        reader = new BufferedReader(new   InputStreamReader(incomingSocket.getInputStream()));
    } catch (IOException e) {
        System.out.println(e);
    }
}

public void openWriter(Socket incomingSocket){

    try {
        writer = new DataOutputStream(incomingSocket.getOutputStream());
    } catch (IOException e) {
        System.out.println(e);
    }
}

public void openLocalReader(){
    localReader = new BufferedReader(new InputStreamReader(System.in));
}

public String readLocalData(){
    String data = null;

    try {
        data = localReader.readLine();
    } catch (IOException e) {
        System.out.println(e + " readLocalData()");
    }
    return data;
}

public String readSocketData(){
    String data = null;

    try {
        data = reader.readLine();
    } catch (IOException e) {
        System.out.println(e + " readSocketData()");
    }
    return data;
}

}

1 个答案:

答案 0 :(得分:1)

java.net.SocketException: Socket closed readSocketData()
java.net.SocketException: Socket closed writeData(String data)
  

我当然明白这些错误意味着什么

他们的意思是你关闭了套接字并继续使用它。

  

但我不明白为什么他们出现因为我有一个while循环,我检查客户端是否连接。

不,你没有。你有一个while循环,在其中检查客户端 socket 是否仍然打开,根本不是同一个东西......但是在任何情况下都不会阻止你在循环中使用一个封闭的套接字,例如在closeConnection()中关闭它后,其返回值从它的前面回到了前面应该是无疑造成混淆,据我所知,这是由两个线程调用的。