Java多线程客户端/服务器通信故障

时间:2012-04-12 23:33:19

标签: java multithreading sockets network-programming client-server

我正在编写服务器 - 客户端聊天程序。服务器正确等待传入连接并创建一个线程( IdentThread )来验证用户(询问用户名密码)。在确认用户身份后, IdentThread 会创建一个 ChatThread 来处理用户输入并将消息发送给其他用户及其关联的客户端。

客户端程序通过缓冲读取器从命令行读取,使用 PrintWriter 将消息发送到服务器,并使用另一个 BufferedReader <接收消息/强>

此模型运作良好。但是,当用户断开连接然后重新连接时,他们会很好地通过 IdentThread ,但在输入 ChatThread 后,服务器或其他用户的所有消息都不可见。我找到的唯一办法就是重新启动服务器程序,这在实际应用中是不可行的。

服务器启动一个新的 IdentThread ,将套接字传递给套接字,让它接受套接字并启动它。

IdentThread 会创建一个新的 BufferedReader PrintWriter 来处理 I / O 。无论客户端多少次连接和断开连接,它们都会一直工作。

通过身份验证后, IdentThread 会创建一个 ChatThread ,并向其传递套接字,用户名,用户ID号,BufferedReader和PrintWriter。

这是我遇到问题的地方。用户连接和断开连接一次后,他们就无法再读取服务器发送给他们的任何消息,尽管他们可以从 IdentThread 中读取消息。用户发送的消息对其他用户可见,服务器正确响应用户发送的命令。

我不确定问题是否是由于我从未有任何绑定到套接字的事实引起的,就像我正在进行通信工作或其他一些我不知道的问题。

编辑:我发布了一些代码,并引入了处理通信的部分。

我觉得问题可能来自我如何将ChatThreads分配给客户

服务器主:

public class Main{

public static boolean listening = false;
public static AtomicInteger connec = new AtomicInteger(0);
public static AtomicInteger onln = new AtomicInteger(0);
public static Hashtable<String, String> passlist = new Hashtable<String, String>();
public static Hashtable<String, Integer> privslist = new Hashtable<String, Integer>();
public static String[] online = new String[20];
public static ChatThread[] clients = new ChatThread[20];

public static void main(String[] args) throws IOException{

    ServerSocket listener = null;
    int port = 6667;
    int backlog = 20;
    int maxconnec = 20;

    passlist.put("apoc326", "password");
    privslist.put("apoc326", 5);
    passlist.put("jameson", "password");
    privslist.put("jameson", 0);

    //create a new server socket
    listener = new ServerSocket(port, backlog);
    listening = true;
    System.out.println("Starting listening to the socket for an incoming connection.");

    //if the server is listening for new connections and
    //the maximum number of connections hasn't been reached
    while(listening == true && connec.get() < maxconnec){

        //create a new thread to perform user login and increment number of connections
        System.out.println("Listening...");
        new IdentThread(listener.accept()).start();
        connec.incrementAndGet();
    }

    //close the server socket
    listener.close();
}

}

IdentThread:

public class IdentThread extends Thread{

private Socket mysock = null;
private PrintWriter out = null;
private BufferedReader in = null;

IdentThread(Socket sock){

    mysock = sock;
}

public void run(){

    try{
        out = new PrintWriter(mysock.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(mysock.getInputStream()));

            //A whole mess of code removed

    if(validName == true && validPass == true){
        synchronized(this){
            for(int i = 0; i < Main.clients.length; i++){
                if(Main.clients[i] == null){
                    //add the user's name to the list of online users
                    ID = i;
                    Main.online[i] = username;
                    Main.clients[i] = new ChatThread(mysock, username, ID, in, out);
                    Main.clients[i].start();
                    Main.onln.incrementAndGet();

ChatThread:

public class ChatThread extends Thread{

private Socket mysock = null;
private PrintWriter out = null;
private BufferedReader in = null;
private boolean online = true;
private String input = null;
private String output = null;
private int ID = -1;

//constructor
ChatThread(Socket sock, String name, int ID, BufferedReader in, PrintWriter out){

    mysock = sock;
    username= name;
    alias = name;
    this.in = in;
    this.out = out;
    this.ID = ID;
    privs = Main.privslist.get(username);

}

//executable section of the thread
public void run(){

    while(online == true){


            try {
                input = in.readLine();
            } 
            catch (IOException e) {
                e.printStackTrace();
                break;
            }

            output = parse(input);

            if(output != null){
                sendAll(output);
            }
    }

    try {
        in.close();
        out.close();
        mysock.close();
        Main.onln.decrementAndGet();
        Main.connec.decrementAndGet();
        System.out.println(username + " has disconnected. Online user count: " + Main.onln.get());
        System.out.println("ChatThread " + ID + " terminating. Connection count: " + Main.connec.get());
    } 
    catch (IOException e) {
        e.printStackTrace();
    }
}

客户端:

public class Main {

public static void main(String args[]) throws IOException{

    BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
    String servIP = null;
    int port = 6667;
    PrintWriter out = null;
    BufferedReader in = null;
    Socket mysock = null;
    boolean connected = false;
    String incoming = null;
    String outgoing = null;

    servIP = console.readLine();

    mysock = new Socket(servIP,port);

    out = new PrintWriter(mysock.getOutputStream(), true);
    in = new BufferedReader(new InputStreamReader(mysock.getInputStream()));

    connected = true;

    while(connected == true){

        while(in.ready()){
            incoming = in.readLine();
            System.out.println(incoming);
        }

        while(console.ready()){
            outgoing = console.readLine();
            out.println(outgoing);

            if(outgoing.equals("/disco")){
                connected = false;
                break;
            }
        }
    }

    in.close();
    out.close();
    console.close();
    mysock.close();
}

0 个答案:

没有答案