无法向所有客户端Java发送消息

时间:2015-02-24 11:28:51

标签: java client server

我正在使用A服务器,它可以接收来自所有客户端的消息并将其发送给其他人。我可以接收消息,但我不能向所有客户发送信息,尽管我从所有客户那里得到了正确的流。

这是我的代码 如果你想测试,请cmd - > telnet localhost端口号

import java.io.*;
import java.util.*;
import java.net.*;

public class Server 
{

    private ServerSocket s;
    private Hashtable saveOutputStreams =  new Hashtable(500,80);

    //Constructor
    public Server(int port) throws IOException
    {
        listen(port);
    }
    //Listen method
    public void listen(int port) throws IOException
    {
        s = new ServerSocket(port);

        while(true)
        {
            Socket incoming = s.accept();

            OutputStream sout = incoming.getOutputStream();

            saveOutputStreams.put(incoming, sout);
            Runnable r = new ThreadHandler(this,incoming);
            Thread t = new Thread(r);
            t.start();
        }
    }
    // Create a table of streams to process in for loop of senToAll method
    Enumeration getOutputStreams()
    {
        return saveOutputStreams.elements();
    }
    // Send message to all clients
    public void sendToAll(String message)
    {
        synchronized(saveOutputStreams)
        {
            for(Enumeration e = getOutputStreams();e.hasMoreElements();)
            {

                OutputStream getOut = (OutputStream)e.nextElement();
                PrintWriter outp  = new PrintWriter(getOut);

                try
                {
                    outp.println("sent"+ message);
                    System.out.println("Stream: "+getOut);
                    System.out.println("PrinWriter "+outp);

                }
                catch(Exception ie)
                {
                    ie.printStackTrace();
                    System.out.println("Error");
                }

                finally
                {
                    System.out.println("done sen To All");
                }
            }
        }
    }
    // Main
    public static void main(String []args) throws IOException
    {
        new Server(8015);
    }
}

class ThreadHandler implements Runnable
{
    private Socket incoming;
    private Server serverP;

    public ThreadHandler(Server server, Socket socket)
    {
        serverP = server;
        incoming = socket;
    }

    public synchronized void run()
    {
        try
        {
            try
            {

                InputStream inStream = incoming.getInputStream();
                OutputStream outStream = incoming.getOutputStream();

                Scanner in = new Scanner(inStream);
                PrintWriter out = new PrintWriter(outStream,true);

                out.println("TungAnh'Server");
                String message = in.nextLine();
                serverP.sendToAll(message);

                out.println("receieve: "+message);
                out.println("done");
                System.out.println("current Stream: "+ outStream);
                System.out.println("PrinWriter "+ out);

            }
            finally
            {
                incoming.close();
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我改进了你的代码:

  1. 删除了奇怪的日志记录
  2. 添加了实例管理
  3. 添加了一些关闭的流
  4. ...
  5. 如果您要使用我的代码,您一定要看看同步(我的方法是同步的,但它们应该与同一个锁定对象/类同步)和异常处理。我不能在这个问题上花更多的时间,对不起。

    结果(对我有用):

    package test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.PrintWriter;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    
    public class Server 
    {
    
        private ServerSocket s;
    
        //Constructor
        public Server(int port) throws IOException
        {
            listen(port);
        }
        //Listen method
        public void listen(int port) throws IOException
        {
            s = new ServerSocket(port);
    
            while(true)
            {
                Socket incoming = s.accept();
                Runnable r = new ThreadHandler(this,incoming);
                Thread t = new Thread(r);
                t.start();
            }
        }
    
        // Main
        public static void main(String []args) throws IOException
        {
            new Server(8015);
        }
    }
    
    class ThreadHandler implements Runnable
    {
        private Socket incoming;
    
        private static List<ThreadHandler> instances = new ArrayList<ThreadHandler>();
    
        public synchronized void addInstance() {
            instances.add(this);
        }
    
        public synchronized void removeInstance() {
            instances.remove(this);
        }
    
        public ThreadHandler(Server server, Socket socket)
        {
            incoming = socket;
            addInstance();
        }
    
        public synchronized void sendToAll(String msg, ThreadHandler me) {
            for (ThreadHandler h : instances) {
                if (h == me) continue;
    
                OutputStream outStream = null;
                PrintWriter print = null;
                try {
                    outStream = h.incoming.getOutputStream();
                    print = new PrintWriter(outStream);
                    print.println(msg);
                    print.flush();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
        public synchronized void run()
        {
            try
            {
                try
                {
    
                    InputStream inStream = incoming.getInputStream();
                    OutputStream outStream = incoming.getOutputStream();
    
                    Scanner in = null;
                    try {
                        in = new Scanner(inStream);
    
                        PrintWriter out = new PrintWriter(outStream,true);
    
                        out.println("Vojta's Server");
    
                        while (true) {
                            try {
                                String message = in.nextLine();
                                sendToAll(message, this);
                            } catch (Exception e) {
    
                            }
    
                        }
    
    
                    } catch (Exception e) {
    
                    }
                    finally {
                        if (in != null) {
                            in.close();
                        }
                    }
                }
                finally
                {
                    incoming.close();
                }
            }
            catch(IOException e)
            {
                e.printStackTrace();
            } finally {
                removeInstance();
            }
        }
    }