我正在与ServerSocketChannel创建聊天并维护客户端 - 服务器之间的通信。 服务器从客户端接收消息并向每个客户端广播。 我试图向服务器发送消息,一切都很好,但当我尝试从服务器向客户端发送消息时,消息无法到达。它仅在我关闭套接字时提供。 (就像它被缓冲了一样)
这是我的服务器代码:
static public void main( String args[] ) throws Exception {
// Parse port from command line
int port = Integer.parseInt( args[0] );
try {
// Instead of creating a ServerSocket, create a ServerSocketChannel
ServerSocketChannel ssc = ServerSocketChannel.open();
// Set it to non-blocking, so we can use select
ssc.configureBlocking( false );
// Get the Socket connected to this channel, and bind it to the
// listening port
ServerSocket ss = ssc.socket();
InetSocketAddress isa = new InetSocketAddress( port );
ss.bind( isa );
// Create a new Selector for selecting
Selector selector = Selector.open();
// Register the ServerSocketChannel, so we can listen for incoming
// connections
ssc.register( selector, SelectionKey.OP_ACCEPT );
System.out.println( "Listening on port "+port );
while (true) {
// See if we've had any activity -- either an incoming connection,
// or incoming data on an existing connection
int num = selector.select();
// If we don't have any activity, loop around and wait again
if (num == 0) {
continue;
}
// Get the keys corresponding to the activity that has been
// detected, and process them one by one
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()) {
// Get a key representing one of bits of I/O activity
SelectionKey key = it.next();
// What kind of activity is it?
if ((key.readyOps() & SelectionKey.OP_ACCEPT) ==
SelectionKey.OP_ACCEPT) {
// It's an incoming connection. Register this socket with
// the Selector so we can listen for input on it
Socket s = ss.accept();
clientList.add(new Client(s));
System.out.println( "Got connection from "+s );
// Make sure to make it non-blocking, so we can use a selector
// on it.
SocketChannel sc = s.getChannel();
sc.configureBlocking( false );
// Register it with the selector, for reading
sc.register( selector, SelectionKey.OP_READ );
} else if ((key.readyOps() & SelectionKey.OP_READ) ==
SelectionKey.OP_READ) {
SocketChannel sc = null;
try {
// It's incoming data on a connection -- process it
sc = (SocketChannel)key.channel();
boolean ok = processInput( sc );
/* HERE, TRYING TO SEND A TEST MESSAGE BACK */
ByteBuffer bf = ByteBuffer.allocate(48);
bf.clear();
bf.put("testmessage".getBytes());
sc.write(bf);
// If the connection is dead, remove it from the selector
// and close it
if (!ok) {
key.cancel();
Socket s = null;
try {
s = sc.socket();
System.out.println( "Closing connection to "+s );
s.close();
} catch( IOException ie ) {
System.err.println( "Error closing socket "+s+": "+ie );
}
}
} catch( IOException ie ) {
// On exception, remove this channel from the selector
key.cancel();
try {
sc.close();
} catch( IOException ie2 ) { System.out.println( ie2 ); }
System.out.println( "Closed "+sc );
ie.printStackTrace();
}
}
}
// We remove the selected keys, because we've dealt with them.
keys.clear();
}
} catch( IOException ie ) {
System.err.println( ie );
}
}
在服务器上,请注意以下行:
ByteBuffer bf = ByteBuffer.allocate(48);
bf.clear();
bf.put("testmessage".getBytes());
sc.write(bf);
这是我试着回答的地方。
客户端通过以下方法接收消息:
// Main method for incoming
public void run() throws IOException {
while(true) {
InputStream is = con.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String answer = br.readLine();
printMessage(answer);
}
}
此致 佩德罗
答案 0 :(得分:1)
这里有几个问题。
read()
获得-1。在那之后你几乎肯定无法发送它。readLine()
获取null时,您的客户端读取循环需要中断。