服务器不接受nio中的多个客户端

时间:2012-06-19 11:24:42

标签: java networking nio

我正在尝试构建聊天应用程序。我有一个代码可以将数据从客户端发送到服务器。当一个或多个客户端登录时(当客户端程序运行一次或多次时).server将不接受除首次连接之外的其余连接。 请帮我解决这个问题 这是我的代码:

public class Server
{

//Creating non blocking socket

public void non_Socket() throws Exception {

    ServerSocketChannel ssChannel = ServerSocketChannel.open();
    int port = 80;
    int i=0;
    ssChannel.socket().bind(new InetSocketAddress(port));
    ssChannel.configureBlocking(false);
    while(true)
    {
        SocketChannel sc = ssChannel.accept();`

        if (sc == null) 
        {
            System.out.println("Socket channel is null");
            Thread.sleep(5000);
        }
        else 
        {
            System.out.println("Socket channel is not null");
            System.out.println("Received an incoming connection from " +
                    sc.socket().getRemoteSocketAddress()); 
            new PrintRequest(sc,i).start(); 
            i++;
        }
    }
}

public static void main(String [] abc) throws Exception
{
    new Server().non_Socket();
}
}

class PrintRequest extends Thread {

public  PrintRequest(SocketChannel sc,int i) throws Exception
{
    WritableByteChannel wbc = Channels.newChannel(System.out); 
    ByteBuffer b = ByteBuffer.allocateDirect(1024); // read 1024 bytes 
    int numBytesRead = sc.read(b);

    while (numBytesRead != -1) 
    {
        b.flip();

        while (b.hasRemaining())
        { 
            wbc.write(b);
            System.out.println();
            //System.out.println("Stream  "+i);
            // System.out.println("  KKK   "+b.toString());
        }
        //b.clear();
    }    
}
}

客户代码:

public class Client extends Thread {

public void non_Client_Socket() throws Exception
{
    SocketChannel sChannel = SocketChannel.open();
    sChannel.configureBlocking(false);
    sChannel.connect(new InetSocketAddress("localhost", 80));
    while (!sChannel.finishConnect())
    {
        System.out.println("Channel is not connected yet");
    }

    System.out.println("Channel is ready to use");

    /* ----------  going to send data to server ------------*/   
    System.out.println("please enter the text");
    BufferedReader stdin=new BufferedReader(new InputStreamReader(System.in));
    while(true)
    {
        System.out.println("Enter the text");
        String HELLO_REQUEST =stdin.readLine().toString();
        if(HELLO_REQUEST.equalsIgnoreCase("end"))
        {
            break;
        }

        System.out.println("Sending a request to HelloServer");    
        ByteBuffer buffer = ByteBuffer.wrap(HELLO_REQUEST.getBytes());    
        sChannel.write(buffer); 
     }
}
     /* ----------  the data is written to sChannel server
                      will read from this channel  ------------   */

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

2 个答案:

答案 0 :(得分:4)

这里有很多问题。

  1. 您正在将ServerSocketChannel置于非阻止模式,然后在不使用选择器的情况下调用accept()。这意味着99.9999%的时间accept()将返回null,因此您正在燃烧CPU周期。这毫无意义。在阻止模式下接受或使用选择器。

  2. 您正在将客户端SocketChannel置于非阻止模式,在不使用选择器的情况下调用connect(),和调用finishConnect()。这意味着99%的时间finishConnect()将返回false,因此您正在燃烧CPU周期。这毫无意义。要么以阻止模式连接,要么使用选择器。

  3. 您忽略了SocketChannel.write()的结果。你不能这样做。它会返回您需要了解的信息。

  4. 简而言之,您的代码没有多大意义。

答案 1 :(得分:3)

我没有时间详细查看您的代码,但有些初步观察:

  1. 使用NIO时,建议您使用Selector(我在your previous question中建议),而不是每个客户端使用一个帖子。

  2. 请记住bind每个客户端,以便允许服务器套接字accept新连接。