如何解决ServerSocketChannel接收http请求,一个请求接收两次
我想使用NIO ServerSocket接收http请求,代码如下所示。然后,我使用邮递员发送一个简单的请求,例如“ http:// localhost:8067 / servlet / MonkeyServlet”。令人惊讶的是,我得到了两个可接受的密钥,其中一个客户端的输入流为空。 然后,我编写了一个IO套接字进行比较。这次,我只有一个可接受的客户端,并且remoteSocketAddress与NIO不同,我不明白为什么会发生这种情况,请给我一些建议。
public class AsyncSocketServer {
private static final String responseHeader200 = "HTTP/1.1 200 OK\r\n" +
"Server: Chinese-country-dog\r\n" +
"Content-Length:148\r\n\r\n"+
"<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
"<meta charset=\"utf-8\">\n" +
"<title>Chinese-country-dog</title>\n" +
"</head>\n" +
"<body>\n" +
" <h1>This is a Monkey</h1>\n" +
"</body>\n" +
"</html>";
private final int port;
private static final int BUFFER_SIZE = 1024;
public AsyncSocketServer(int port){
this.port = port;
}
public static void main(String[] args) throws Exception{
AsyncSocketServer server = new AsyncSocketServer(8067);
server.start();
}
public void start() throws IOException {
ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
ServerSocket serverSocket = server.socket();
serverSocket.bind(new InetSocketAddress(port));
Selector selector = Selector.open();
selector.wakeup();
server.register(selector,SelectionKey.OP_ACCEPT);
final ByteBuffer msg = ByteBuffer.wrap(responseHeader200.getBytes());
while(true){
try{
selector.select();
}catch (IOException ex){
ex.printStackTrace();
break;
}
Set<SelectionKey> readyKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = readyKeys.iterator();
while(iterator.hasNext()){
SelectionKey key = iterator.next();
iterator.remove();
try{
if(key.isAcceptable()){
System.out.println("-----------------------------------------------------------");
ServerSocketChannel serverChannel = (ServerSocketChannel)key.channel();
SocketChannel client = serverChannel.accept();
client.configureBlocking(false);
client.register(selector,SelectionKey.OP_READ);
System.out.println(client.getRemoteAddress());
}
if(key.isWritable()){
SocketChannel client = (SocketChannel)key.channel();
ByteBuffer buffer = (ByteBuffer)key.attachment();
while(buffer.hasRemaining()){
if(client.write(buffer) == 0){
break;
}
}
client.close();
continue;
}
if(key.isReadable()){
SocketChannel socket = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
StringBuilder builder = new StringBuilder();
while (socket.read(buffer) > 0) {
buffer.flip();
while (buffer.hasRemaining()){
builder.append((char)buffer.get());
}
buffer.clear();
}
System.out.println(builder.toString());
socket.register(selector,SelectionKey.OP_WRITE,msg.duplicate());
}
}catch (IOException ex){
key.cancel();
try{
key.channel().close();
}catch (IOException cex){
}
}
}
}
}
}
结果1:
-----------------------------------------------------------
/0:0:0:0:0:0:0:1:56403
-----------------------------------------------------------
/0:0:0:0:0:0:0:1:56404
GET /servlet/MonkeyServlet HTTP/1.1
User-Agent: PostmanRuntime/7.26.5
Accept: */*
Cache-Control: no-cache
Postman-Token: 47975c62-ec4e-4ca8-ac4f-d7c1de59331e
Host: localhost:8067
Accept-Encoding: gzip,deflate,br
Connection: keep-alive
public class SyncSocketServer {
private static final String responseHeader200 = "HTTP/1.1 200 OK\r\n" +
"Server: Chinese-country-dog\r\n" +
"Content-Length:148\r\n\r\n"+
"<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
"<meta charset=\"utf-8\">\n" +
"<title>Chinese-country-dog</title>\n" +
"</head>\n" +
"<body>\n" +
" <h1>This is a Monkey</h1>\n" +
"</body>\n" +
"</html>";
private final int port;
public SyncSocketServer(int port){
this.port = port;
}
public static void main(String[] args){
SyncSocketServer server = new SyncSocketServer(8067);
server.start();
}
public void start(){
ServerSocket serverSocket = null;
try{
serverSocket = new ServerSocket(port,1,InetAddress.getByName("127.0.0.1"));
}catch (IOException e){
e.printStackTrace();
}
while (true) {
Socket socket = null;
try {
socket = serverSocket.accept();
System.out.println("-----------------------------------------------------------");
System.out.println(socket.getRemoteSocketAddress());
socket.setSoTimeout(1);
InputStream inputStream = socket.getInputStream();
StringBuilder builder = new StringBuilder();
int c;
try {
while ((c = inputStream.read())>0){
builder.append((char)c);
}
}catch (SocketTimeoutException e){
//ignore
}
System.out.println(builder.toString());
socket.getOutputStream().write(responseHeader200.getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
if(!socket.isClosed()){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
结果2:
-----------------------------------------------------------
/127.0.0.1:56670
GET /servlet/MonkeyServlet HTTP/1.1
User-Agent: PostmanRuntime/7.26.5
Accept: */*
Cache-Control: no-cache
Postman-Token: 02bf641c-65c0-4cc1-a874-090260d0bef9
Host: localhost:8067
Accept-Encoding: gzip,br
Connection: keep-alive
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。