jjfjjj 发表于 2017-1-31 13:10:45

tomcat 7 源码分析-9 tomcat对ServerSocket的封装和使用


tomcat 7 源码分析-9 tomcat对ServerSocket的封装和使用

  tomcat中ServerSocket线程监听是否有socket连接,如果有就转而处理。这个过程类似于你向tomcat发送一个URL请求,实质这个请求转换成http协议,通过socket发出来。
  先看ServerSocket的封装主要为

Java代码  





[*]
public
 
abstract
 
class
 ServerSocketFactory 
implements
 Cloneable  




public abstract class ServerSocketFactory implements Cloneable
 
Java代码  





[*]
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 {
returnnew 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发消息。

Java代码  





[*]
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
}
}
}
}

 
Java代码  





[*]
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
  当然也可以写个客户端,向服务器端发数据。

Java代码  





[*]
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();  
[*]
        }  
[*]
          
[*]
    }  
[*]
  
[*]


页: [1]
查看完整版本: tomcat 7 源码分析-9 tomcat对ServerSocket的封装和使用