两个服务器提供文件共享服务。 1. 服务器A和服务器B提供文件上传下载服务。服务器A是主服务器,服务器B是备用服务器。
2. 有5个客户端同时上传不同的大文件(200M~500M),当上传开始1分钟后随意启动N个客户端(命令行输入),每个客户端在这5个上传中的文件中随机选择一个文件下载
3. 中间突然停掉服务器A并保持服务器B继续服务 整个过程能顺利进行,所有下载的文件是完整并且正确的。请用Java编写,不用写界面。 请高手给点思路,thankyou。
2. 有5个客户端同时上传不同的大文件(200M~500M),当上传开始1分钟后随意启动N个客户端(命令行输入),每个客户端在这5个上传中的文件中随机选择一个文件下载
3. 中间突然停掉服务器A并保持服务器B继续服务 整个过程能顺利进行,所有下载的文件是完整并且正确的。请用Java编写,不用写界面。 请高手给点思路,thankyou。
解决方案 »
- Exception in thread "main" java.lang.NullPointerException at Server.main(Server.java:22)
- 每日一题4
- 在求个正则表达式……
- 没有报错,功能却不能实现,没有天理啊,急,在线等
- p2p通信中实现穿墙技术
- 想写一个类似QQ的JAVA通信程序,是否该用线程池??
- SOS~!(在线等待)
- 奇怪的问题,关于cpu占用
- 有一个问题偶很感兴趣,可不知如何实现,请大家帮忙
- java似乎对我来说没有前途,我做了一个类似于oicq的程序,但是要求客户端必须安装10多兆的java运行环境.java在客户端好象根本没有生存空间可言.而本人却致力于客户端软件的发展.请问专家,我的看法是否正确?
- 畅谈null布局,求交流
- java中的list、map比较
package com.huawei.test;import java.rmi.Remote;
import java.rmi.RemoteException;/**
* 远程接口定义
*/
public interface RemoteMethod extends Remote
{
/**
* 远程文件上传
*
* @param String : 文件磁盘路径
* @throws RemoteException
* @return void
*/
public String sendUp(String filePath) throws RemoteException;
}package com.huawei.test;import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;/**
* 远程核心服务器端
*
* 启动远程服务,注册远程对象
*/
public class TaskServerA
{
/* 远程接口实现类 */
private RemoteMethodImp remoteMethodImp;
public TaskServerA(String pathFile)
{
try
{
//new Thread(remoteMethodImp = new RemoteMethodImp(pathFile)).start();
remoteMethodImp = new RemoteMethodImp(pathFile);
}
catch (RemoteException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
/* 启动远程服务 */
serverStart();
}
/**
* 远程服务器启动远程对象绑定
*
* @exception RemoteException, RemoteException,
* MalformedURLException
* @return void
*/
public void serverStart()
{
/* 远程服务端口 */
try
{
LocateRegistry.createRegistry(8888);
}
catch (RemoteException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
/* 注册远程对象 */
try
{
final String KIDNAPPER = "rmi://191.169.50.199:8888//remoteMethodImp";
Naming.rebind(KIDNAPPER, remoteMethodImp);
System.out.println("远程核心服务器启动...");
}
catch (RemoteException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
catch (MalformedURLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
}
/**
* @param args
*/
public static void main(String[] args)
{
TaskServerAFactory.getTaskServerA();
}
}/**
* 核心服务器工厂类
*/
class TaskServerAFactory
{
public static TaskServerA getTaskServerA()
{
/* 测试客户端上传文件 */
final String filePath = "F:/value.txt";
return new TaskServerA(filePath);
}
}未完待续,今天没时间了,要开会。
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;public class Server {
private ServerSocket serverSocket = null;
private Socket socket = null; public void getFile(int port) {
try {
serverSocket = new ServerSocket(port);
System.out.println("server start....");
while (true) {
socket = serverSocket.accept(); System.out.println(socket.getInetAddress()
+ " is connected the server..."); Thread serverThread = new ServerThread(socket);
serverThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
} class ServerThread extends Thread {
private Socket socket; public ServerThread(Socket socket) {
this.socket = socket;
} public void run() {
File file = null; DataInputStream in = null;
DataOutputStream out = null; try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
if (in.readChar() == '?') {
downloadFile(in, out, file);
} else {
uploadFile(in, out, file);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
if (out != null)
out.close();
if(socket!=null){
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} public void uploadFile(DataInputStream in, DataOutputStream out,
File file) {
try {
String fileName = null;
StringBuffer stringBuffer = new StringBuffer();
char c = '\\';
while ((c = in.readChar()) != '\\') {
stringBuffer.append(c);
}
fileName=stringBuffer.toString().substring(0, stringBuffer.length());
file = new File("e:\\back\\" + fileName);
long pointer=in.readLong();
out.writeLong(file.length());
if(file.length()==0){
out.write(-1);
}else if(file.length()-pointer > -1){
in = new DataInputStream(new FileInputStream(file));
int i = -1;
byte[] buffer = new byte[1024*512];
while ((i = in.read(buffer)) != -1) {
out.write(buffer, 0, i);
pointer+=i;
}
out.write(-1);
}else{
out.write(-1);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
if (out != null)
out.close();
if(socket!=null){
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} } public void downloadFile(DataInputStream in, DataOutputStream out,
File file) {
try {
String fileName = null;
StringBuffer stringBuffer = new StringBuffer();
char c = '\\';
while ((c = in.readChar()) != '\\') {
stringBuffer.append(c);
}
fileName = socket.getInetAddress() + "-"
+ stringBuffer.toString();
file = new File("e:\\back\\" + fileName); out.writeLong(file.length()); out = new DataOutputStream(new FileOutputStream(file, true)); int i = -1;
byte[] buffer = new byte[1024];
while ((i = in.read(buffer)) != -1) {
out.write(buffer, 0, i);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
if (out != null)
out.close();
if(socket!=null){
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Properties;public class Client extends Thread {
private Properties props = new Properties();
private String serverIP;
private int serverPort;
private String backupIP;
private int backupPort;
private Socket socket;
public Properties getProps() {
return props;
} public void setProps(Properties props) {
this.props = props;
} public String getServerIP() {
return serverIP;
} public int getServerPort() {
return serverPort;
} public String getBackupIP() {
return backupIP;
} public int getBackupPort() {
return backupPort;
} public Client() {
props.setProperty("serverIP", "localhost");
props.setProperty("serverPort", "9999");
props.setProperty("backupIP", "localhost");
props.setProperty("backupPort", "8989"); this.serverIP = "localhost";
this.serverPort = 9999;
this.backupIP = "localhost";
this.backupPort = 8989;
} public void upLoad(String filePath,String IP,int port) {
long pointer = 0;
File file = new File(filePath); DataInputStream in = null;
DataOutputStream out = null;
try {
socket=getSocket(IP, port);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream()); // 发送文件名
out.writeChars("?" + file.getName() + "\\"); // 得到指针
pointer = in.readLong();
System.out.println("pointer==" + pointer);
if (file.length() - pointer > -1) {
System.out.println("开始上传...");
in = new DataInputStream(
new FileInputStream(new File(filePath)));
in.skip(pointer);
int i = -1;
byte[] buffer = new byte[1024*512];
while ((i = in.read(buffer)) != -1) {
sleep(100);
out.write(buffer, 0, i);
pointer += i;
}
out.write(-1);
}
System.out.println("上传完毕");
} catch (SocketException e) {
if (socket.getPort()==this.serverPort) {
try {
if (in != null)
in.close();
if (out != null)
out.close();
if (socket != null)
socket.close();
System.out.println("切换服务器...");
upLoad(filePath,this.backupIP,this.backupPort);
} catch (IOException e1) {
e.printStackTrace();
}
} else {
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
if (out != null)
out.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
} }
} public void download(String filePath,String fileName,String IP,int port) {
File file = new File(filePath+fileName);
System.out.println("filelength==="+file.length());
if(file.length()<1){
File tempFile = new File(filePath+fileName+".tmp");
System.out.println("tempFilelength===="+tempFile.length());
long fileSize=0;
DataInputStream in = null;
DataOutputStream out = null;
try {
socket=getSocket(IP, port);
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
out.writeChars(" "+fileName+"\\");
out.writeLong(tempFile.length());
fileSize=in.readLong();
System.out.println("filesize===="+fileSize);
out = new DataOutputStream(new FileOutputStream(tempFile, true)); int i = -1;
byte[] buffer = new byte[1024 * 512];
while ((i = in.read(buffer)) != -1) {
out.write(buffer, 0, i);
}
System.out.println(tempFile.length()-fileSize);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(tempFile.length()==fileSize){
}
try {
if (in != null)
in.close();
if (out != null)
out.close();
if(tempFile.length()-fileSize > -1)
renameFile(tempFile, filePath,fileName,0);
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
} }
}
}
public boolean renameFile(File tempFile,String filePath,String fileName,Integer i) throws IOException{
File file =null;
if(i==0){
file = new File(filePath+fileName);
}else{
file = new File(filePath+i+"-"+fileName);
}
if(tempFile.renameTo(file)){
return true;
}
if(i<255){
return renameFile(tempFile, filePath, fileName, i+1);
}
return false;
}
@SuppressWarnings("finally")
public Socket getSocket(String IP,int port) throws UnknownHostException, IOException{
if(this.socket!=null){
System.out.println(this.socket.getInetAddress()+":"+(IP)+"===:==="+ (this.socket.getPort()+":"+port));
if(this.socket.getInetAddress().equals(IP)&& this.socket.getPort()==port){
return this.socket;
}else{
return new Socket(IP,port);
}
}else{
return new Socket(IP,port);
}
} public static void main(String[] args) {
Client client = new Client();
//client.upLoad("e:\\a.jpg",client.getServerIP(), client.getServerPort());
client.download("e:\\back\\download\\","127.0.0.1-a.jpg",client.getServerIP(), client.getServerPort());
}
}
很有创意的想法
第一印象觉得很不可思议;
仔细想想光从热备的要求上来说,上传的时候备份服务器同步处理信息应该可以!
再想想,不对,A都挂了,客户端怎么知道B是来接班的?
IP漂移,那就不是JAVA能干的事
就算JAVA能干,进行中的事务不可能完美过渡
你的文件假设在A机上传/下载了10个包,同时这些动作同步映射到B服务器;
这些过程中,客户端只联系A,而不管B,B上的信息是由A主动让B进行同步;
当A处理到第11个包的时候,挂了,却没有把第11个包的内容发送给B,而客户端的确是把包已经发送出去了,A也告诉它收到了,这时候你让B从哪里变出第11个包?
也许可以让服务器对数据进行颗粒化处理,颗粒有序编号,每个服务器都标明自己当前事务的处理进度,当B接管的时候回应客户端“你发给我的是12,我连11都还没有呢,从11开始”
还有很多想法,说不完了,高可用性不是纯粹用代码写出来的!!!
你只要做到服务器确定你完成了整个上传下载过程的时候,正确告诉客户端,同时客户端再来个反馈,像TCP/IP的三次握手那样;
另外,一定要着重确保,服务器不保存发生错误的数据;
也就是保证事务是完整的,而不保证事务总是被执行;
即使现在数据库这么牛X的年代,一个SQL执行一半,机器挂了,也没那个厂商的数据库服务器能做到这个SQL非得给我执行完不可!!!
知道你写的代码多,不跟你抢分!
我从头到尾都只是简单的陈诉自己的思考过程,你这么激动干嘛!
ORACLE我是写不出来,我就不问下一句了,免得多事!
A和B的同步确实无法做到100%保证,正如你所说的我们可以在A接受到数据的时候写入A本地的文件,同时发送输出给B,但是可能A正好接受到一半的数据,也就是代码执行到发送给B的时候A挂掉,数据就产生了不同步但是数据的完整性还是可以确保的,文件都是有长度的,客户端在A挂掉之后会捕获到一个SocketException
这时候客户端去和B建立socket,然后先发送本地文件长度,B接收到之后判断B的本地文件长度发送回客户端
客户端通过判断如果B的文件长度小于客户端本地的文件长度,就把B的文件长度作为指针开始读取本地文件输出给B,这样就不会出现数据错误了,A和B的服务器其实启动的时候并不能直接启动服务,而是启动服务器之间的文件同步操作,一旦同步完成才开始启动针对客户端的服务,下载同理最后驳一句,高性能还真就是代码写出来的,要是没有代码的话,执行
long j=2;
for(long i =2;i<10000000;i++){
j=i*j;
}
代码效率高了很多,要是用纸和比,要算多久哦-。-
楼主我认识的,只是探讨思路,我觉得提出自己的思路或者提出问题比较有意义,这里本来就是个面试题,并不是实际实现,面试题给出的环境就是要求用java,我们也没办法啊,java的执行效率自然比不上c++这是先天决定的,没办法,目前还没有编译器能够让编译出来的java速度和c++一样另外就是你说的问题,IO传输效率低下,需要借助第三方工具包,我不太明白,能说下是什么工具包么?
java本身来说IO是比较底层的输入输出方式了,单纯的说效率其实和c++比倒没有真的差距那么大,关键还是看IO的次数,
不过我想在此问一下,可不可以在上传到a服务器的时候,将b服务器实现同步复制呢。
可以实现伪同步,完全同步不太现实,上面我说了,如果A执行到同步给B的时候正好挂掉的话,A的数据就比B要多,伪同步的实现方法蛮多了,最简单的就是A在接收到客户端发送过来的数据包的时候应该执行输出到文件,这时候只要多加一句把A接收到从客户端哪里接收到的数据包原封不动的给B就可以了
但是要是深入点想的话就影响效率了,因为这时候客户会发下一个发送数据过来,但是A要先传输给B完成后才能再接收,这样的话客户就需要等待了,这里如果要提高效率就得启动新线程用来输出给B,但是要记得同步控制否则的话是异步的,可能会出现后面的包写在前面的包之前