java - 多线程客户端/服务器应用程序java问题

标签 java multithreading sockets client chat

这是我的第一篇文章,如果我做错了什么,请纠正我。

我正在尝试制作一个多线程客户端/服务器应用程序。我在没有线程的情况下制作基本的一对一客户端/服务器应用程序没有问题,但我希望每个客户端单独与服务器对话,并且每个客户端仅接收属于控制台中特定客户端的消息。这是我无法使其发挥作用的地方。

我在网上看了一些教程,并尝试在 Eclipse 中调试,但没有成功。 我希望应用程序执行以下操作:

如果我运行服务器和 2 个客户端,我希望能够在客户端上写入消息并使服务器返回消息和消息编号而不跳过编号。

客户端 1:

消息编号:0。您说:您好!

消息编号:1.你说:怎么了!

客户端2:

消息编号:0。您说:嘿服务器!

消息号:1.你说:你现在在做什么?

它与我运行的第一个客户端一起工作并完美地增加了消息编号,但是当我创建第二个客户端时它卡住了,所以我想我的问题要么是套接字声明,要么是我的线程方式。 (也许某个地方缺少 socket.close() ?)

我知道该应用程序还存在一些其他缺陷,但请记住,这只是使用线程的学校作业。

如果有人愿意提供帮助,请提前致谢。 :)

服务器代码:

public class Server extends Thread 
{   
  DataInputStream in;
  DataOutputStream out;
  ServerSocket listener;

public Server() throws IOException
{      
    try 
    {
        while (true) 
        {
            listener = new ServerSocket(9090);
            Socket socket = listener.accept(); 
            System.out.println("Test");
            ThreadServer ts = new ThreadServer(socket);
            Thread t1 = new Thread(ts);
            t1.start();   
        }
    }
    finally 
    {
        listener.close();
    }   
}

public static void main(String[] args) throws IOException 
{
    new Server();
}
}

客户端代码:

public class Client extends JFrame 
 {      
   DataOutputStream dos;
   BufferedReader input;
   String answer = null;
   String textString;
   Socket s = new Socket("localhost", 9090);

public Client() throws IOException
{
    JButton btn = new JButton("run");
    final JTextField txf = new JTextField(10);
    btn.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {             
            try 
            {   
                dos = new DataOutputStream(s.getOutputStream());
                textString = txf.getText();
                dos.writeUTF(textString);
                dos.flush();        
                input = new BufferedReader(new InputStreamReader(s.getInputStream()));
                answer = input.readLine();                      
            } 
            catch (Exception e1) 
            {
                e1.printStackTrace();
            }           
                System.out.println(answer); 
            }       
    });
    setLayout(new GridLayout(2,2));
    add(btn);
    add(txf);
    setVisible(true);
    pack();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

public static void main(String[] args) throws IOException 
{
    new Client();
}
}

线程服务器代码:

public class ThreadServer implements Runnable
{
  DataInputStream in;
  DataOutputStream out;

public ThreadServer (Socket socket) throws IOException
{       
    int i = 0;  

    try 
    {
        while (true) 
        {            
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());

            try 
            {
                String message = in.readUTF();          
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                out.println("Message no: " + i + ". You said: " + message);                  
                out.println("Message no: " + i);
            }
            catch(Exception e) 
            {
                e.printStackTrace();
            }
            i++;
        }
    }
    finally 
    {
        socket.close();
    }
}

@Override
public void run() {
    // TODO Auto-generated method stub

}
  }

最佳答案

让我尝试解决这个问题。

  • 仅创建一个ServerSocket。从 while 循环移至以下行。将其放在 while 循环之前。

    listener = new ServerSocket(9090);
    
  • ThreadServer 构造函数的代码移至 run() 方法,因为它实现了 Runnable,但行为与一个Runnable类。

    public ThreadServer(Socket socket) throws IOException {
        this.socket=socket;
    }
    
    @Override
    public void run() {
       ...
       //code from constructor
    }
    
  • 在服务器类中,您向客户端写入两行,但客户端仅读取一行。删除多余的行,如下所示

    out.println("Message no: " + i + ". You said: " + message);
    //out.println("Message no: " + i);
    

最后一个建议:

在调用 readUTF() 之前始终检查输入,如下所示:

if (in.available() > 0) {
    try {
        String message = in.readUTF();
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        out.println("Message no: " + i + ". You said: " + message);
        //out.println("Message no: " + i);
    } catch (Exception e) {
        e.printStackTrace();
    }
    i++;
}

关于java - 多线程客户端/服务器应用程序java问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23117861/

相关文章:

java - 披萨订购计划

java - 我的程序没有以执行器返回/结束

c - 本地 linux 套接字接收旧数据

java - 检测客户端何时不再监听服务器

java - 使用 RESTful API 进行自定义验证

java - 为什么我应该更新 java jdk 1.6 Web 应用程序,不更新会有什么风险?

java - 无法找到 XML 模式命名空间的 Spring NamespaceHandler [http ://www. springframework.org/schema/context]

iphone - 在线程中解除分配

c++ - QThreadPool & QRunnable & 静态函数

linux - 如何使用 native 网络系统从 Pd Vanilla > 0.46 控制 VLC?