【问题标题】:server not accepting morethan one client in nio服务器在 nio 中不接受多个客户端
【发布时间】:2012-06-20 18:01:03
【问题描述】:

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

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();
}
}

【问题讨论】:

  • 您在这里发布代码时已经严重破坏了您的代码,所以我可能错了,但是:它看起来像您的“新 PrintRequest(sc,i).start();”应该创建一个新线程,但它不会。尝试:“新线程(新 PrintRequest(sc,i)).start();”。
  • @AlexLynch PrintRequest extends Thread 所以你的评论不正确。
  • @EJP 我明白了;自从我看到它以来,他清理了他的代码。无论如何,PrintRequest 的代码并没有在它自己的线程中运行。代码应该在 run() 方法而不是它的构造函数中,否则它会阻塞在主线程上。
  • @Alex 实际上它应该与选择器在 same 线程中运行:这是 NIO。整个事情都是错误的。他发布了另一个正在讨论的问题。

标签: java networking nio


【解决方案1】:

这里有很多问题。

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

  2. 您正在将您的客户端 SocketChannel 置于非阻塞模式,调用 connect(), 和调用 finishConnect() 而不使用选择器。这意味着 99% 的时间 finishConnect() 将返回 false,因此您正在消耗 CPU 周期。这是没有意义的。以阻塞模式连接或使用选择器。

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

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

【讨论】:

  • 是的,你完全正确,我与不同的客户建立了联系
【解决方案2】:

我没有时间详细研究您的代码,但有一些初步观察:

  1. 在使用 NIO 时,我建议您使用 Selector(正如我在 your previous question 中建议的那样),而不是每个客户端一个线程。

  2. 记住bind每个客户端为了允许服务器套接字accept新连接。

【讨论】:

  • @Amith 那么你为什么要使用 NIO?在非阻塞模式下,NIO 用于节约线程。
猜你喜欢
  • 1970-01-01
  • 2016-10-05
  • 2015-10-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 2015-02-14
  • 2021-11-01
  • 1970-01-01
相关资源
最近更新 更多