📄 server.java
字号:
import java.net.*;
import java.io.*;
import java.util.Date.*;
import java.awt.*;
import java.awt.event.*;
public class Server implements Runnable
{
private abc frame;
//在放弃之前尝试连接远程主机的次数
public int CONNECT_RETRIES=5;
//在两次连接尝试之间的暂停时间
public int CONNECT_PAUSE=5;
//等待Socket输入的等待时间
public int TIMEOUT=50;
//Socket输入的缓冲大小
public int BUFSIZ=1024;
//是否要求代理服务器在日志中记录所有已传输的数据(true表示“是”)。
static public boolean logging = false;
//一个OutputStream对象,默认日志例程将向该OutputStream对象输出日志信息
static public OutputStream log=null;
//允许最大连接
static public int MAXUSER=20;
//用户连接数量
static public int count=0;
//Socket对象
protected Socket socket;
private String parent=null;
private int parentPort=-1;
public void setParentProxy(String name, int pport)
{
parent=name;
parentPort=pport;
}
public Server(Socket s,abc frame)
{
socket=s;
this.frame=frame;
}
public void writeLog(int c, boolean browser) throws IOException
{
log.write(c);
}
public void writeLog(byte[] bytes,int offset, int len, boolean browser) throws IOException
{
for (int i=0;i<len;i++) writeLog((int)bytes[offset+i],browser);
}
public String processHostName(String url, String host, int port, Socket sock)
{
java.text.DateFormat cal=java.text.DateFormat.getDateTimeInstance();
System.out.println(cal.format(new java.util.Date()) + " - " + url + " "
+ sock.getInetAddress()+"\n");
frame.jLog.append(cal.format(new java.util.Date()) + " - " + url + " "
+ sock.getInetAddress()+"\n");
return host;
}
public void run()
{
if(count>MAXUSER)
{
//用户超过指定连接数目,向用户发送用户过多网页
try
{
System.out.println("用户超过指定");
PrintStream out =new PrintStream(socket.getOutputStream());
out.println("HTTP/1.0 200 OK");
out.println("MIME_version:1.0");
out.println("Content_Type:text/html");
String msg="<html> <head</head><body> <hl> 连接用户数量过多,请稍后再试!</jl></Body></html>";
out.println("Content_Length:"+msg.length());
out.println(" ");
out.print(msg);
}catch (IOException ex){}
try
{
socket.close();
}
catch (Exception e1) {}
}
else
{
count++;
String line;
String host;
int port=80;
Socket outbound=null;
try
{
//Socket的超时时间
socket.setSoTimeout(TIMEOUT);
//获得输入流
InputStream is=socket.getInputStream();
OutputStream os=null;
try
{
// 获取请求行的内容
line="";
host="";
int state=0;
boolean space;
while (true)
{
//字节流结束返回-1
int c=is.read();
if (c==-1)
break;
if (logging)
writeLog(c,true);
space=Character.isWhitespace((char)c);
switch (state)
{
case 0:
if (space)
// 跳过多个空白字符
continue;
state=1;
case 1:
if (space)
{
state=2;
continue;
}
line=line+(char)c;
break;
case 2:
if (space)
// 跳过多个空白字符
continue;
state=3;
case 3:
if (space)
{
state=4;
// 只取出主机名称部分
String host0=host;
int n;
n=host.indexOf("//");
if (n!=-1)
host=host.substring(n+2);
n=host.indexOf('/');
if (n!=-1)
host=host.substring(0,n);
// 分析可能存在的端口号
n=host.indexOf(":");
if (n!=-1)
{
port=Integer.parseInt(host.substring(n+1));
host=host.substring(0,n);
}
host=processHostName(host0,host,port,socket);
if (parent!=null)
{
host=parent;
port=parentPort;
}
int retry=CONNECT_RETRIES;
while (retry--!=0)
{
try
{
outbound=new Socket(host,port);
break;
}
catch (Exception e) { }
// 等待
Thread.sleep(CONNECT_PAUSE);
}
if (outbound==null)
{
//请求的网页无法获得的情况
System.out.println("获取网页不存在或者服务器无法取得网页");
PrintStream out =new PrintStream(socket.getOutputStream());
out.println("HTTP/1.0 200 OK");
out.println("MIME_version:1.0");
out.println("Content_Type:text/html");
String msg="<html> <head</head><body> <hl> 你所请求的网页不存在,或服务器无法获得网页,请与管理员联系!</jl></Body></html>";
out.println("Content_Length:"+msg.length());
out.println(" ");
out.print(msg);
try
{
socket.close();
count--;
}
catch (Exception e1) {}
break;
}
//打开Socket之后,run先把部分的请求写入Socket,然后调用pipe方法。
outbound.setSoTimeout(TIMEOUT);
os=outbound.getOutputStream();
os.write(line.getBytes()); //line=get
os.write(' ');
os.write(host0.getBytes()); //获得的ie信息
os.write(' ');
pipe(is,outbound.getInputStream(),os,socket.getOutputStream());
break;
}
host=host+(char)c;
break;
}
}
}
catch (IOException e) { }
}
catch (Exception e) { }
finally
{
try
{
socket.close();
count--;
}
catch (Exception e1) {}
try
{
outbound.close();
}
catch (Exception e2) {}
}
}
}
//pipe方法直接在两个Socket之间以最快的速度执行读写操作。
void pipe(InputStream is0, InputStream is1,
OutputStream os0, OutputStream os1) throws IOException
{
try
{
int ir;
byte bytes[]=new byte[BUFSIZ];
while (true)
{
try
{
if ((ir=is0.read(bytes))>0)
{
os0.write(bytes,0,ir); //发送
if (logging)
writeLog(bytes,0,ir,true);
}
else
if (ir<0)
break;
}
catch (InterruptedIOException e) { }
try
{
if ((ir=is1.read(bytes))>0) //得到数据
{
os1.write(bytes,0,ir); //发送数据
if (logging)
writeLog(bytes,0,ir,false);
}
else if (ir<0)
break;
}
catch (InterruptedIOException e) { }
}
}
catch (Exception e0)
{
//超时异常
System.out.println("代理服务器的转换出现了异常 " + e0);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -