3

I am a student on holiday and I decided to make a server application for fun. So the problem is: My class - Server.java - is a server created with ServerSocket, but when I try to construct a Thread class - ServerThread.java - something I have never seen before happens. I debugged the class and when I step into the constructor of ServerThread called in Server.java, it doesn't go into ServerThread but instead goes into ClassLoader.class. I assume this normally also happens at some point, but now only this gets called and not the constructor of ServerThread.

I have been struggling with this for the past 3 days, almost non-stop, but for the love of Pete I cannot get it to work.

Here is my Server.java code:

    public class Server
{
private ArrayList<Socket> sockets;
private ServerSocket ss;

// Constructor and while-accept loop all in one.
public Server( int port ) throws IOException
{   
    Runtime.getRuntime().addShutdownHook(new Thread()
    {
        @Override
        public void run()
        {
            try {
                ss.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    });

    // All we have to do is listen
    listen( port );
}

// Main routine
// Usage: java Server >port<
static public void main( String args[] ) throws Exception
{
    // Get the port # from the command line
    int port = 5003;
    // Create a Server object, which will automatically begin
    // accepting connections.
    new Server( port );
}

private void listen( int port ) throws IOException
{
    // Create the ServerSocket
    ss = new ServerSocket(port, 0, InetAddress.getByName("10.0.0.6"));
    // Tell the world we're ready to go
    System.out.println( "Listening on " + ss );

    sockets = new ArrayList<Socket>();

    // Keep accepting connections forever
    while (true)
    {
        // Grab the next incoming connection
        Socket s = ss.accept();
        // Tell the world we've got it
        System.out.println( "Connection from " + s );

        sockets.add(s);
        // Create a new thread for this connection, and then forget
        // about it
        new ServerThread( this, s );
    }
}

public void removeConnection(Socket socket) throws IOException
{
    synchronized (sockets) 
    {
        sockets.remove(socket);
        System.out.println("Closing connection at " + socket);
        socket.close();
    }
}

public void sendToAll(Socket s, String msg) throws IOException
{
    synchronized (sockets) 
    {
        for (int i = 0; i < sockets.size(); i++)
        {
            if (!sockets.get(i).equals(s))
            {
                new BufferedWriter(new OutputStreamWriter(sockets.get(i).getOutputStream())).write(msg);
            }
        }
    }
}
}

And here is my ServerThread.java code:

    public class ServerThread extends Thread
{
private Server server;
private Socket socket;

public ServerThread( Server server, Socket socket )
{
    // Save the parameters
    this.server = server;
    this.socket = socket;
    // Start up the thread
    start();
}

// This runs in a separate thread when start() is called in the
// constructor.
public void run()
{
    try
    {
        // Create a DataInputStream for communication; the client
        // is using a DataOutputStream to write to us
        BufferedReader din = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        // Over and over, forever ...
        while (true)
        {
            String message = "";
            try
            {
                // ... read the next message ...
                message = din.readLine();
                // ... tell the world ...
                System.out.println( "Sending "+message );

                server.sendToAll(socket, message);
            }
            catch (SocketException ex)
            {
                break;
            }
            System.out.println("GG");
        }
    }
    catch( EOFException ie )
    {
        ie.printStackTrace();
        System.out.println("GG1");
    }
    catch( IOException ie )
    {
        // This does; tell the world!
        ie.printStackTrace();
        System.out.println("GG2");
    }
    finally
    {
        // The connection is closed for one reason or another,
        // so have the server dealing with it
        try {
            server.removeConnection( socket );
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
}

I hope I have made myself clear enough...

4

2 回答 2

0

如果您正在逐步调试并且遇到new需要当前卸载的类的表达式,您进入类加载器。

这是正常行为。您可能需要多次退出才能返回您的代码。

于 2013-06-12T22:52:22.910 回答
-1

好的。原来构造函数被调用,但程序挂在 din.readLine()。我不知道为什么会这样,因为我确实在消息末尾添加了一个 '\n' 字符,所以我改为将 BufferedReader 和 BufferedWriter 对象更改为 java.io.DataInputStream 和 java.io.DataOutputStream 并使用readUTF() 和 writeUTF() 方法,这很有效。谢谢大家的回答和时间:)。

于 2013-06-13T13:22:16.467 回答