我正在尝试构建聊天应用程序。我有一个代码可以将数据从客户端发送到服务器。当一个或多个客户端登录时(当客户端程序运行一次或多次时).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();
}
}
答案 0 :(得分:4)
这里有很多问题。
您正在将ServerSocketChannel
置于非阻止模式,然后在不使用选择器的情况下调用accept()
。这意味着99.9999%的时间accept()
将返回null,因此您正在燃烧CPU周期。这毫无意义。在阻止模式下接受或使用选择器。
您正在将客户端SocketChannel
置于非阻止模式,在不使用选择器的情况下调用connect(),
和调用finishConnect()
。这意味着99%的时间finishConnect()
将返回false,因此您正在燃烧CPU周期。这毫无意义。要么以阻止模式连接,要么使用选择器。
您忽略了SocketChannel.write()
的结果。你不能这样做。它会返回您需要了解的信息。
简而言之,您的代码没有多大意义。
答案 1 :(得分:3)
我没有时间详细查看您的代码,但有些初步观察:
使用NIO时,建议您使用Selector
(我在your previous question中建议),而不是每个客户端使用一个帖子。
请记住bind
每个客户端,以便允许服务器套接字accept
新连接。