5

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

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

2 回答 2

4

这里有很多问题。

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

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

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

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

于 2012-06-20T10:01:03.350 回答
3

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

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

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

于 2012-06-19T11:30:30.657 回答