tomcat 7 源码分析-9 tomcat对ServerSocket的封装和使用
tomcat中ServerSocket线程监听是否有socket连接,如果有就转而处理。这个过程类似于你向tomcat发送一个URL请求,实质这个请求转换成http协议,通过socket发出来。
先看ServerSocket的封装主要为
- public abstract class ServerSocketFactory implements Cloneable
public abstract class ServerSocketFactory implements Cloneable
- class DefaultServerSocketFactory extends ServerSocketFactory {
- DefaultServerSocketFactory () {
- /* NOTHING */
- }
- @Override
- public ServerSocket createSocket ( int port)
- throws IOException {
- return new ServerSocket (port);
- }
- @Override
- public ServerSocket createSocket ( int port, int backlog)
- throws IOException {
- return new ServerSocket (port, backlog);
- }
- @Override
- public ServerSocket createSocket ( int port, int backlog,
- InetAddress ifAddress)
- throws IOException {
- return new ServerSocket (port, backlog, ifAddress);
- }
- @Override
- public Socket acceptSocket(ServerSocket socket)
- throws IOException {
- return socket.accept();
- }
- @Override
- public void handshake(Socket sock)
- throws IOException {
- // NOOP
- }
- }
class DefaultServerSocketFactory extends ServerSocketFactory {
DefaultServerSocketFactory () {
/* NOTHING */
}
@Override
public ServerSocket createSocket (int port)
throws IOException {
return new ServerSocket (port);
}
@Override
public ServerSocket createSocket (int port, int backlog)
throws IOException {
return new ServerSocket (port, backlog);
}
@Override
public ServerSocket createSocket (int port, int backlog,
InetAddress ifAddress)
throws IOException {
return new ServerSocket (port, backlog, ifAddress);
}
@Override
public Socket acceptSocket(ServerSocket socket)
throws IOException {
return socket.accept();
}
@Override
public void handshake(Socket sock)
throws IOException {
// NOOP
}
}
做了个小例子,模拟8080端口,可以通过浏览器想serversocket发消息。
- package com.test.socket;
- import java.io.*;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- import org.apache.tomcat.util.net.*;
- public class testendpoint {
- protected volatile boolean running = false ;
- /**
- * Server socket acceptor thread.
- */
- protected ServerSocket serverSocket = null ;
- protected ServerSocketFactory serverSocketFactory = null ;
- public void start() throws Exception {
- running = true ;
- //获得serverSocketFactory
- serverSocketFactory = ServerSocketFactory.getDefault();
- //获得serverSocket,监听8080端口
- serverSocket = serverSocketFactory.createSocket(8080 );
- //建立监听线程
- Thread acceptorThread = new Thread( new Acceptor(), "-Acceptor-" );
- acceptorThread.start();
- }
- //处理socket
- protected boolean processSocket(Socket socket) throws IOException {
- BufferedReader in = new BufferedReader( new InputStreamReader(
- socket.getInputStream()));
- String inputLine;
- while ((inputLine = in.readLine()) != null ) {
- System.out.println(inputLine);
- }
- return true ;
- }
- //监听类,不断循环
- protected class Acceptor implements Runnable {
- /**
- * The background thread that listens for incoming TCP/IP connections and
- * hands them off to an appropriate processor.
- */
- public void run() {
- // Loop until we receive a shutdown command
- while (running) {
- // Loop if endpoint is paused
- // Accept the next incoming connection from the server socket
- try {
- Socket socket = serverSocketFactory.acceptSocket(serverSocket);
- serverSocketFactory.initSocket(socket);
- // Hand this socket off to an appropriate processor
- if (!processSocket(socket)) {
- // Close socket right away
- try {
- socket.close();
- } catch (IOException e) {
- // Ignore
- }
- }
- }catch ( IOException x ) {
- } catch (Throwable t) {
- }
- // The processor will recycle itself when it finishes
- }
- }
- }
- }
package com.test.socket;
import java.io.*;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import org.apache.tomcat.util.net.*;
public class testendpoint {
protected volatile boolean running = false;
/**
* Server socket acceptor thread.
*/
protected ServerSocket serverSocket = null;
protected ServerSocketFactory serverSocketFactory = null;
public void start() throws Exception {
running = true;
//获得serverSocketFactory
serverSocketFactory = ServerSocketFactory.getDefault();
//获得serverSocket,监听8080端口
serverSocket = serverSocketFactory.createSocket(8080);
//建立监听线程
Thread acceptorThread = new Thread(new Acceptor(),"-Acceptor-");
acceptorThread.start();
}
//处理socket
protected boolean processSocket(Socket socket) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
return true;
}
//监听类,不断循环
protected class Acceptor implements Runnable {
/**
* The background thread that listens for incoming TCP/IP connections and
* hands them off to an appropriate processor.
*/
public void run() {
// Loop until we receive a shutdown command
while (running) {
// Loop if endpoint is paused
// Accept the next incoming connection from the server socket
try {
Socket socket = serverSocketFactory.acceptSocket(serverSocket);
serverSocketFactory.initSocket(socket);
// Hand this socket off to an appropriate processor
if (!processSocket(socket)) {
// Close socket right away
try {
socket.close();
} catch (IOException e) {
// Ignore
}
}
}catch ( IOException x ) {
} catch (Throwable t) {
}
// The processor will recycle itself when it finishes
}
}
}
}
- package com.test.socket;
- import org.apache.tomcat.util.net.*;
- public class Servertest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- testendpoint ts = new testendpoint();
- try {
- System.out.println("Server start" );
- ts.start();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
package com.test.socket;
import org.apache.tomcat.util.net.*;
public class Servertest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
testendpoint ts = new testendpoint();
try {
System.out.println("Server start");
ts.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试,在你的浏览器上输入:http://localhost:8080/
可以看见发过来的request的整个消息
Server start
GET / HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.7) Gecko/20100713 Firefox/3.6.7
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
当然也可以写个客户端,向服务器端发数据。
- package com.test.socket;
- import java.net.Socket;
- import java.net.UnknownHostException;
- import java.io.*;
- public class ClientTest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- //String host="127.0.0.1";
- String host = "localhost" ;
- Socket socket = null ;
- try {
- socket = new Socket(host, 8080 );
- } catch (UnknownHostException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- } catch (IOException e1) {
- // TODO Auto-generated catch block
- e1.printStackTrace();
- }
- try {
- PrintWriter out = new PrintWriter(socket.getOutputStream(), true );
- out.println("Send to host1" );
- out.println("Send to host2" );
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }