|
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 {
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发消息。
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();
}
}
}
|
|
|