0

嗨,我为客户端和服务器编写了代码,现在我想在 clint 1 到 clint 2 之间传递消息,我没有成功在服务器端执行此操作我想为名称和 id 构造数组,并且在我从客户端发送消息之后我可以选择服务器发送消息的位置或名称请帮我写这个,所以这是克林特的一面

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;


public class client {

    public static void main(String[] args) {
        Socket socket = null; 
        try {
            socket = new Socket("127.0.0.1", 7777);
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedReader readerFromCommandLine = new BufferedReader(new InputStreamReader(System.in));
            PrintWriter writer = new PrintWriter(socket.getOutputStream());

            while(true) {                               
                System.out.println("Say something:");
                String userInput = readerFromCommandLine.readLine();
                writer.println(userInput);
                writer.flush();

                String input = reader.readLine();               

                System.out.println("Got from server: "+input);

                if (userInput.equalsIgnoreCase("bye")) {
                    break;
                }
            }
        }
        catch(Exception e) {
            System.err.println(e);
            e.printStackTrace();
        }
        finally {
            if (socket != null) {               
                try {
                    socket.close();
                } 
                catch (Exception e) {
                    System.err.println(e);
                    e.printStackTrace();
                }               
            }
        }
    }

}

所以现在我的代码看起来像这样?因为我还不能从一个客户发送到客户二

import java.awt.List;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;


public class server {

    public static void main(String[] args) {
        ArrayList<Channel> my_clients = new ArrayList<Channel>(); 
        ServerSocket ss = null;

        try {
            ss = new ServerSocket(7777);            

            while (true) {
                //wait for a new client call - once got it, get the socket for
                //that channel

                System.out.println("Waiting for an incoming call");
                Socket client = ss.accept();
                Channel my_new_client = new Channel(client); 
                my_clients.add(my_new_client); 
                my_new_client.start();
                //once the call has started read the client data
                for(Channel my_client : my_clients) { 
                    if(my_client.getName() == "Me") { 
                        //my_client.writer("HELLO!"); 

                    }
                }
                //System.out.println("Accepted a new call");                                
                //new Channel(client).start();

            }
        }
        catch(Exception e) {
            System.err.println(e);
            e.printStackTrace();
        }
        finally {
            if (ss != null) {
                try {
                    ss.close();
                }
                catch(Exception e) {
                    System.err.println(e);
                    e.printStackTrace();
                }
            }
        }

    }



     public static class Channel extends Thread {

         private static int clientIndex = 0;
         private int index;

        private Socket socket = null;

        public Channel(Socket socket) {
            clientIndex++;
            index = clientIndex;
            this.socket = socket;
        }

        @Override
        public void run() {

            try {
                BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                PrintWriter writer = new PrintWriter(socket.getOutputStream());

                while (true) {  

                    String input = reader.readLine();                   
                    System.out.println("Got from client "+index+": "+input);

                    //bye bye
                    if (input.equalsIgnoreCase("bye")) {
                        break;
                    }
                    writer.println("Gotcha");
                    writer.flush();                         
                }
            }
            catch(Exception e) {
                System.err.println(e);
                e.printStackTrace();
            }
            finally {
                if (socket != null) {
                    try {
                        socket.close();
                    }
                    catch(Exception e) {
                        System.err.println(e);
                        e.printStackTrace();
                    }
                }
            }
        }

    }

}
4

2 回答 2

0

String userInput = readerFromCommandLine.readLine();

BufferedReader.readLine() 在这里是个问题。它会阻塞你的线程,直到收到输入。这意味着通信一次只能朝一个方向进行,并且如果两个客户端都在等待,则可能会完全阻塞。

DataFetcher 可以解决这个问题;您可以使用它在单独的线程中收听

http://tus.svn.sourceforge.net/viewvc/tus/tjacobs/io/

于 2012-05-18T14:35:15.570 回答
0

你到了一半。

您创建了一个线程服务器,来自客户端的每个连接都会打开一个线程。然后该线程循环并等待消息。

当您将客户端与它们自己的对象/属性及其要写入和读取它们的流连接时,请考虑这些线程。

因此,每次您想要创建他们的线程的客户端连接时,将其添加到某种列表并启动他们的线程。例如:

在班上名列前茅

List<Channel> my_clients = new List<Channel>();

在你的 while 循环中

Channel my_new_client = new Channel(client);
my_clients.add(my_new_client);
my_new_client.start();

然后当你想向某个客户发送消息时。您可以循环所有线程并查找具有某种名称或唯一标识符的线程。例如:

for(Channel my_client : my_clients) {
    if(my_client.getName() == "Me") {
        my_client.write("HELLO!");
    }
}

或者您可以同时向所有客户发送消息(广播):

for(Channel my_client : my_clients) {
    my_client.write("HELLO!");
}

记得在客户端断开连接时删除它们!

// Can't remember the precise exception correct my if I'm wrong!
catch(SocketException ex) {
     my_clients.remove(this);
}

请注意,这需要您了解如何验证并知道您的客户端的名称,或者为他们提供一个 UID,当您被指示向他们发送某些内容时,您可以参考该 UID。并且 Channel 类具有纵容的 Write 方法。

希望有帮助!

于 2012-05-18T14:41:18.863 回答