如何用JAVA实现一个代理服务器

如何用JAVA实现一个代理服务器,第1张

搂主说得很对,这个必须使用多线程得原理来做,一个线程用于监听后台事件,一个线程用于客户得 *** 作
即:一个线程初始化类用于服务器端的双线程产生
服务端所有 *** 作都必须是以线程得形式出来(当然如果你能自己实现一个线程池是最好的)。
客户端则是平常得Socket *** 作

如果你学过网络基础的话,应该知道现在流行的tcp/ip协议,Java支持的是网络层或ip层以上的 *** 作。
有很多种传递的方法,Java SE里面就有RMI方式,或Socket方式(分tcp和udp两种)。这些都属于C/S的方式。
另外Java EE里面以B/S方式主要是用客户端向服务器端的servlet/jsp发起请求实现的,其底层用的是><soapenv:Header/>
<soapenv:Body>
<api:getEmp>
<shopId>string</shopId>
</api:getEmp>
</soapenv:Body>
</soapenv:Envelope>
这个时SOAP协议的标准报文格式,客户端只要发送这样的报文给支持SOAP协议的webservice服务器即可成功调用web service服务
服务端:部署服务只需要自己定义服务的接口和实现类,并用@webservice注解,通过endPoint类直接发布即可

楼上的太长了吧,我写个简单的
import javanet;
import javaio;
import javautil;
/
TCP协议下单向通信的客户端程序。
@author new

/
public class TCPClientA {
public static void main(String[] args) {
Socket s=null;
try {
s=new Socket("127001",8888);
BufferedReader br=new BufferedReader(new InputStreamReader(sgetInputStream()));
String str=brreadLine();
Systemoutprintln(str);
} catch (Exception e) {
eprintStackTrace();
}finally{
if(s!=null)try{sclose();}catch(IOException e){}
}
}
}
================================
import javanet;
import javaio;
import javautil;
/
TCP协议下单向通信的服务器端程序。
@author new

/
public class TCPServerA {
public static void main(String[] args) {
ServerSocket ss=null;
Socket s=null;
PrintStream ps=null;
try {
ss=new ServerSocket(8888);
while(true){
Systemoutprintln("服务器已启动,在8888端口:");
s=ssaccept();
Systemoutprintln("得到 "+sgetInetAddress()+" 的连接请求");
ps=new PrintStream(sgetOutputStream());
psprintln(new Date());
psflush();
Systemoutprintln("已向客户端发送数据!");
}
} catch (IOException e) {
eprintStackTrace();
}finally{
if(ps!=null)psclose();
if(s!=null)try{sclose();}catch(IOException e){}
if(ss!=null)try{ssclose();}catch(IOException e){}
}
}
}

import javaio;
import javanet;public class ftpServer extends Thread{ public static void main(String args[]){
String initDir;
initDir = "D:/Ftp";
ServerSocket server;
Socket socket;
String s;
String user;
String password;
user = "root";
password = "123456";
try{
Systemoutprintln("MYFTP服务器启动");
Systemoutprintln("正在等待连接");
//监听21号端口
server = new ServerSocket(21);
socket = serveraccept();
Systemoutprintln("连接成功");
Systemoutprintln("");
Systemoutprintln("");

InputStream in =socketgetInputStream();
OutputStream out = socketgetOutputStream();

DataInputStream din = new DataInputStream(in);
DataOutputStream dout=new DataOutputStream(out);
Systemoutprintln("请等待验证客户信息");

while(true){
s = dinreadUTF();
if(strim()equals("LOGIN "+user)){
s = "请输入密码:";
doutwriteUTF(s);
s = dinreadUTF();
if(strim()equals(password)){
s = "连接成功。";
doutwriteUTF(s);
break;
}
else{s ="密码错误,请重新输入用户名:";<br> doutwriteUTF(s);<br> <br> }
}
else{
s = "您输入的命令不正确或此用户不存在,请重新输入:";
doutwriteUTF(s);
}
}
Systemoutprintln("验证客户信息完毕"); while(true){
Systemoutprintln("");
Systemoutprintln("");
s = dinreadUTF();
if(strim()equals("DIR")){
String output = "";
File file = new File(initDir);
String[] dirStructure = new String[10];
dirStructure= filelist();
for(int i=0;i<dirStructurelength;i++){
output +=dirStructure[i]+"\n";
}
s=output;
doutwriteUTF(s);
}
else if(sstartsWith("GET")){
s = ssubstring(3);
s = strim();
File file = new File(initDir);
String[] dirStructure = new String[10];
dirStructure= filelist();
String e= s;
int i=0;
s ="不存在";
while(true){
if(eequals(dirStructure[i])){
s="存在";
doutwriteUTF(s);
RandomAccessFile outFile = new RandomAccessFile(initDir+"/"+e,"r");
byte byteBuffer[]= new byte[1024];
int amount;
while((amount = outFileread(byteBuffer)) != -1){
doutwrite(byteBuffer, 0, amount);break;
}break;

}
else if(i<dirStructurelength-1){
i++;
}
else{
doutwriteUTF(s);
break;
}
}
}
else if(sstartsWith("PUT")){
s = ssubstring(3);
s = strim();
RandomAccessFile inFile = new RandomAccessFile(initDir+"/"+s,"rw");
byte byteBuffer[] = new byte[1024];
int amount;
while((amount =dinread(byteBuffer) )!= -1){
inFilewrite(byteBuffer, 0, amount);break;
}
}
else if(strim()equals("BYE"))break;
else{
s = "您输入的命令不正确或此用户不存在,请重新输入:";
doutwriteUTF(s);
}
}

dinclose();
doutclose();
inclose();
outclose();
socketclose();
}
catch(Exception e){
Systemoutprintln("MYFTP关闭!"+e);

}
}}

服务器端代码:
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintStream;
import javanetServerSocket;
import javanetSocket;
/
Socket通讯服务器端
@author 米强

/
public class ServerMain {
public ServerMain() {
try {
// 构造服务器ServerSocket对象,参数为服务器端开放的端口号
ServerSocket ss = new ServerSocket(30102);
Systemoutprintln("服务器准备就绪!");
// 死循环可以使服务器持续处于接收客户端状态
while(true){
// 该方法使程序阻塞,等待客户端的链接,当监听到客户端的链接,创建一个Socket对象与客户端单独会话
Socket s = ssaccept();
// 为了不影响服务器监听其它客户端,这里开启了一个线程,由线程处理与这个客户端的会话
new ServerThread(s)start();
}
} catch (IOException e) {
eprintStackTrace();
}
}
public static void main(String[] args) {
new ServerMain();
}
}
/
服务器端与客户端会话的线程
/
class ServerThread extends Thread {
private Socket s = null;
private BufferedReader read = null;
private PrintStream print = null;
public ServerThread(Socket s) {
thiss = s;
try {
// 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流
read = new BufferedReader(new InputStreamReader(sgetInputStream()));
print = new PrintStream(sgetOutputStream());
} catch (IOException e) {
eprintStackTrace();
}
}
/
线程的运行run方法
/
public void run() {
try {
String message = null;
// 这里循环可以使服务器持续的接收客户端信息。readreadLine()通过输入流读取一段字符串,赋值给message变量,如果message字符串不为“exit”则循环,否则结束循环
while (!(message = readreadLine())equals("exit")){
// 将字符串前面添加“返回:”,再发回客户端
printprintln("返回:" + message);
}
} catch (IOException e) {
} finally {
// 在 finally 代码块中无论如何都会执行下面代码:
try {
// 如果没有关闭Socket
if(!sisClosed()){
// 关闭Socket链接
sclose();
}
} catch (IOException e1) {
e1printStackTrace();
}
}
}
}
客户端代码:
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintStream;
import javanetSocket;
import javanetUnknownHostException;
import javautilScanner;
/
Socket通讯客户端
@author 米强

/
public class ClientMain {
public ClientMain() {
try {
// 构造与服务器通讯的Socket对象,参数为服务器IP地址(String)和端口号(int),端口号需要和服务器端开放的端口号对应
Socket s = new Socket("1921681100", 30102);
// 启动一个线程与服务器通讯,并把链接服务器的Socket对象传递过去
new LinkThread(s)start();
} catch (UnknownHostException e) {
eprintStackTrace();
} catch (IOException e) {
eprintStackTrace();
}
}
public static void main(String[] args) {
new ClientMain();
}

}
/
与服务器通讯的线程
/
class LinkThread extends Thread {
private Socket s = null;
// 输出流
private PrintStream out = null;
// 缓冲输入流
private BufferedReader in = null;
// 录入文字的Scanner对象
private Scanner scanner = null;

public LinkThread(Socket s) {
// 将Socket对象实例保存在全局变量中,因为run方法中我们还要用它断开链接
thiss = s;
try {
// 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流
out = new PrintStream(sgetOutputStream());
in = new BufferedReader(new InputStreamReader(sgetInputStream()));
} catch (UnknownHostException e) {
eprintStackTrace();
} catch (IOException e) {
eprintStackTrace();
}
}

/
线程的运行run方法
/
public void run() {
// 构造Scanner对象
scanner = new Scanner(Systemin);
Systemoutprintln("提示:如果要结束本次会话,请输入“exit”指令!");
try {
// 死循环可以使客户端不断的向服务器发送信息,不用担心循环无法结束,后面的return语句可以结束整个线程。
while(true){
// 提示用户输入文字
Systemoutprint("请输入:");
// 将用户输入的字符串保存在message变量中
String message = scannernextLine();
// 通过输出流发送字符串
outprintln(message);
// 清空缓冲,强制输出
outflush();
// 获取服务器返回的字符串
String str = inreadLine();
// 如果返回的字符串存在
if(str != null){
// 显示在控制台
Systemoutprintln(str);
}else{
// 提示会话结束,并结束线程
Systemoutprintln("本次会话结束!");
return;
}
}
} catch (IOException e) {
eprintStackTrace();
} finally {
// 在 finally 代码块中无论如何都会执行下面代码:
try {
// 如果没有关闭Socket
if(!sisClosed()){
// 关闭Socket链接
sclose();
}
} catch (IOException e1) {
e1printStackTrace();
}
}
}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/12584385.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-26
下一篇 2023-05-26

发表评论

登录后才能评论

评论列表(0条)

保存