import java.io.*;
import java.net.*;
/**
* 这个类实现了一个简单的单线程的代理服务器
*/
public class SimpleProxyServer {
/** 主函数解析参数并把参数传递给runServer */
public static void main(String[] args) throws IOException {
try {
// 检查参数的个数
if (args.length != 3)
throw new IllegalArgumentException("Wrong number of args.");
// 获得命令行参数: 我们要代理的主机和端口
String host = args[0];
int remoteport = Integer.parseInt(args[1]);
int localport = Integer.parseInt(args[2]);
// 显示开始信息
System.out.println("Starting proxy for " + host + ":" +
remoteport + " on port " + localport);
// 开始运行这个服务器
runServer(host, remoteport, localport); // 永不返回
}
catch (Exception e) {
System.err.println(e);
System.err.println("Usage: java SimpleProxyServer " +
"<host> <remoteport> <localport>");
}
}
/**
* 这个方法运行一个单线程的代理服务器,它在指定的本地端口上
* 代理一个主机上的远程端口。它用不返回。
*/
public static void runServer(String host, int remoteport, int localport)
throws IOException {
// 创建一个ServerSocket来监听连接
ServerSocket ss = new ServerSocket(localport);
// 为客户端到服务器和服务器到客户端创建缓冲区
// 我们指定缓冲区为final,使它能够在下面的匿名类中能够被使用
// 注意在每个方向上交换量上的假定
final byte[] request = new byte[1024];
byte[] reply = new byte[4096];
// 这是一个用不返回的服务器,故进入一个无限循环
while(true) {
// 保持与客户端和与服务器连接的socket的变量
Socket client = null, server = null;
try {
// 等待一个本地端口的连接
client = ss.accept();
// 获取客户流,把他们定义成final使得他们在下面的匿名
// 类中能够被使用
final InputStream from_client = client.getInputStream();
final OutputStream to_client = client.getOutputStream();
// 建立一个与真实服务器的连接
// 如果我们不能连上服务器,发送一个错误给客户端
// 取消连接,等待下次连接
try { server = new Socket(host, remoteport); }
catch (IOException e) {
PrintWriter out = new PrintWriter(to_client);
out.print("Proxy server cannot connect to " + host + ":"+
remoteport + ":\n" + e + "\n");
out.flush();
client.close();
continue;
}
// 获得服务器的流
final InputStream from_server = server.getInputStream();
final OutputStream to_server = server.getOutputStream();
// 创建一个线程读取客户端的请求,把请求传递给服务器,我们不得不
// 使用一个独立的线程,因为请求和响应是异步的
Thread t = new Thread() {
public void run() {
int bytes_read;
try {
while((bytes_read=from_client.read(request))!=-1) {
to_server.write(request, 0, bytes_read);
to_server.flush();
}
}
catch (IOException e) {}
// 客户端关闭了同我们的连接,那么也就关闭了我们与服务器的
// 连接。这将造成主线程中服务器与客户端之间的循环退出
try {to_server.close();} catch (IOException e) {}
}
};
// 开始客户端到服务器请求线程的运行
t.start();
// 同时,在主线程中,读取服务器的响应,并把它们传递给客户端。这将
// 与上面提到的客户端到服务器的请求线程并行执行
int bytes_read;
try {
while((bytes_read = from_server.read(reply)) != -1) {
to_client.write(reply, 0, bytes_read);
to_client.flush();
}
}
catch(IOException e) {}
// 服务器关闭同我们的连接,那么我们关闭与客户端的连接
// 这将使另外一个线程退出
to_client.close();
}
catch (IOException e) { System.err.println(e); }
finally { // 不管发生什么关闭线程
try {
if (server != null) server.close();
if (client != null) client.close();
}
catch(IOException e) {}
}
}
}
}
分享到:
相关推荐
【Linux 单线程网络服务器设计】 Linux 单线程网络服务器是一种在Linux操作系统上实现...它特别适用于高并发、低延迟的网络服务,例如Web服务器和代理服务器,其设计思想和关键技术对于系统开发者有着重要的参考价值。
在Java中实现代理服务器涉及到多个关键概念和技术,包括网络编程、多线程以及服务器端的处理逻辑。 首先,我们需要理解Java中的网络编程基础。Java提供了一系列的类库,如`java.net.Socket`和`java.net....
《基于Java多线程的HTTP代理服务器的研究与实现》这篇文档深入探讨了如何利用Java语言构建一个高效的多线程HTTP代理服务器。在信息技术领域,HTTP代理服务器扮演着至关重要的角色,它作为客户端与目标服务器之间的...
4. 多线程或异步处理:为了处理并发的HTTP请求,代理服务器通常需要使用多线程或异步操作。C#的Task类和async/await关键字可以简化异步编程,提高服务器性能。 四、WebSocket子文件的可能用途 WebSocket是一种在...
本篇文章将探讨代理服务器在网络游戏服务器架构中的简单实践,旨在帮助开发者理解如何利用代理服务器提升游戏性能和稳定性。 代理服务器,也称为中间服务器,是网络通信中的一种常见架构模式。在网络游戏中,代理...
每客户单线程实现http 代理服务器,参考网络资源,用VC6.0编写,满足网络程序设计课程的实验要求。
【标题】"VC编写的代理服务器程序"是一个基于Visual C++(VC)开发的网络应用程序,主要用于实现代理服务器的功能。代理服务器在计算机网络中扮演着重要角色,它充当客户端与目标服务器之间的中介,允许用户通过它来...
HTTP代理服务器.zip 每客户端单线程实现 HTTP代理服务器 还有个线程池技术实现 HTTP代理服务器 博客有介绍 每客户端能成功 线程池还有点问题 网络程序设计实验的代码之一 其他资源在本资源有贡献 套接口编程
3. **多线程**:为了同时处理多个客户端请求,代理服务器需要使用多线程技术。在VC++6.0中,可以使用MFC的`CWinThread`类来创建和管理线程。 4. **数据包解析**:代理服务器需要解析客户端发送的HTTP或HTTPS请求,...
本文将详细介绍 HTTP 代理服务器在 Windows 平台下的实现过程,包括代理服务器的建立过程、程序框架结构、数据分析函数和线程函数等内容。 一、HTTP 代理服务器的建立过程 HTTP 代理服务器的建立过程可以分为以下...
在多线程代理IP测试中,我们可以为每个线程分配不同的代理IP,这样可以同时进行多个登录尝试,提高测试效率。例如,创建一个线程池,将每个登录任务作为参数传递给线程,每个线程负责一个登录流程。需要注意的是,多...
ProxyNet 是一个基于C#开发的代理服务器搜索工具,它利用多线程技术来提高搜索效率,能够在短时间内遍历多个网址,寻找...如果你希望深入学习如何在C#中实现多线程代理服务器搜索,这个项目将是一个很好的学习资源。
代理服务器通常需要同时处理多个客户端请求,因此需要使用多线程或异步I/O模型。C++11及更高版本提供了标准库中的std::thread,可以方便地创建和管理线程。另外,还可以考虑使用epoll、kqueue或IOCP等高级I/O模型来...
- 多线程:为了处理并发连接,代理服务器需要使用多线程技术,每个客户端连接都在单独的线程中处理,以避免阻塞其他客户端的请求。 - HTTP协议解析:代理服务器需要解析客户端的HTTP请求,包括方法(GET、POST等)...
1. 单线程模型:每个连接都由一个单独的线程处理,简单但资源消耗大。 2. 多线程模型:通过多线程并发处理多个连接,提高了处理效率。 3. 异步I/O模型:使用select/poll/epoll等机制,非阻塞地处理多个连接,更高效...
实验过程中,你可以选择实现单用户代理服务器或多用户代理服务器。 单用户代理服务器: 这是一个简单的循环服务器,首先创建HTTP代理服务的TCP主套接字监听客户端连接。接收到请求后,解析URL,建立到目标服务器的...
每个线程负责处理一个客户端连接,这样可以确保当多个用户同时发起请求时,代理服务器能够并行处理,避免单一线程导致的阻塞问题,提升了整体性能和用户体验。 【套接字通信】 在客户端与服务器之间的通信中,套接...
本主题聚焦的是“易语言多线程取代理IP即时验证源码”,这是一个涉及到网络编程、多线程技术和代理服务器验证的重要知识点。 1. **多线程技术**:在计算机程序设计中,多线程是让一个程序内同时执行多个任务或操作...
通过njs库,开发者可以利用Nginx的多线程优势,实现JavaScript在服务器端的高性能计算,有效解决了JavaScript单线程带来的问题。然而,需要注意的是,过度使用njs可能会增加服务器的复杂性,因此在选择使用njs时,应...
在C++中实现一个代理服务器涉及到多个关键知识点,包括网络编程基础、套接字编程、多线程处理以及可能的缓存策略。 首先,了解网络编程的基础是必不可少的。这包括TCP/IP协议栈的工作原理,如传输层的TCP协议(用于...