FTP服务端开发?局域网文件传送问题(88分)

  • 主题发起人 主题发起人 hs9206
  • 开始时间 开始时间
H

hs9206

Unregistered / Unconfirmed
GUEST, unregistred user!
1.IDftpsever的用法,具体一点;
2.ftp服务端不用第三方控件(Ics等)怎么开发;
3.求一段代码详细一点(初涉此问题):
服务端:指定文件夹路径===>多个客户端可以同时下载远程服务端的文件.
===>回收所有连接的客户端的文件到服务端。
即:一对多传文件和多对一传文件。

问题是:客户端同时连接时,服务端的只用一个端口接收怎么处理多客户端
的连接请求,并接收他们上传的文件,多客户端同时访问一个文件
是不是要做文件锁定,不太懂,如果用线程的话?
FTP和tcp协议哪一种处理这种问题好一点。
我用UDP广播,做了做差错控制一问一答传输文件,对该环境下的文件传输,不能
做到一对多传文件,和多对一传文件。

分不够可以加!

客户端 ………… 服务端 客户端 …………
|
请求下载文件 | 请求下载文件
| ---------->指定可下载文件<--------- |
下载文件 <--------- ---------->下载文件
| |
下载完成 下载完成

|
发送回收文件命令
发送文件 ----------> | <---------发送文件
回收结束
 
在线等……
请富翁解答!
要分可加!!
 
用delphi 自带indy的idftpserver和idftp控件来传输文件,delphi内有例子,D:/Program Files/Borland/Delphi7/Source/Indy/
 
里面的只有FTP客户端连接,我想要的是FTPserver
还有demo里的indy我早看了,和我的问题差距较大!
问题继续………………………………………………
 
server首先监听指定端口.
其次建立线程处理客户端请求信息,线程处理函数使用while(true),过程为:
...监听...
...while(true)
...begin
....处理连接请求(比如远端请求连接后,可以把服务器上可以下载的文件名全部发送到客户端)....
...receive指定的下载文件名...
...把文件filestream后,networkstram发送...
...一问一答阻塞模式处理......
...缺点为:单线程,单用户....
...扩展为多线程多用户时,将处理客户端请求的代码再写到一个线程里,模式为:第一个线程用于监听,第二个线程用于具体处理下载.
FTP协议属于应用层协议,比TCP传输层协议更抽象而已,但内部使用的仍是面向连接的TCP协议,
...
 
服务器一对多下载的问题,idftpserver自已会处理,服务器端无需任何控制,
服务器一对多上传的问题,可以在服务器上开一个端口,当有客户端要上传时,发送文件名到服务器,服务器在事先定义的文件名列表中查找,如找到文件名,则通知等待1分钟后再试,如未找到则通知允许上传并保存文件名到文件名列表,客户端收到允许上传的指令后开始上传文件,此时其它客户端如想上传同名文件必须等待。客户端上传完毕后,发送上传结束指令和文件名,服务器收到后删除文件名列表中的相应项。此时其它客户端可以上传了。最好再加个时钟,每隔一段时间检查一下文件名列表中有没有死项。
 
多线程处理的话:
200台机子,试想一下那要多少个线程??
而且要做定时循环,文件要锁定非当前客端接收的不可下载,
主要还是IDftpserver的用法,能不能给demo代码呀??
 
最好是用FTP协议实现,IndyFTPServer雾里看花,自己亲自实现要学会很多东西.
http://www.longen.org/E-K/detaile-k/FTP.htm
http://www.pc51.net/c_read10813.html
这些清楚了就不难了。
 
现在初步,这么做
在服务端编程实现一个FTP服务端
用IDudp发送文件信息/下载FTP服务端IP/用户名/密码
文件在服务端的位置/将下载到客户端有本地存储位置
在IDudpserver的read里根据传来的信息
连接ftp,服务端,根据命令判断是上传还是下载
并进行相应操作.
现在只要是FTPser的编程实现.
我用ser_U建已经完成上述功能,就差用idftpserver
编程开发FTPserver了,先给分了,
余下的分就给能编写出ftpser的人了,要代码哦!
 
fossilth2 : 10
hygsxy : 10
jfyes : 10
过几天一起给你们,
 
有没有人可以给出个例子代码说明,这样会比较容易懂
 
不用控件做ftp就是用winsock来做,监听21口作处理。
 
winsock来做的话,容错不好处理,还有好像只能队列等待,不能多用户同时下载
 
因为我最近比较忙为了省时间,所以我用java实现的,用delphi实现比较费时间。(希望能够抛砖引玉)
//////////////////////////////////////
// 服务器端 //
//////////////////////////////////////
package networktransfer;
import javax.swing.*;
import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.*;
import java.io.*;
import java.nio.*;
import java.util.*;
import java.io.FileInputStream;
import java.nio.channels.*;
import java.awt.*;
import javax.swing.border.EtchedBorder;
import javax.swing.border.Border;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
* <p>Title: </p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/

public class ServerMain extends JFrame implements TransferInter,Serializable {
String dir=null;
Properties profile=null;
Properties privilege=null;
FileInputStream proFin=null;
FileInputStream priFin=null;
JPanel jPanel1 = new JPanel();
BorderLayout borderLayout1 = new BorderLayout();
JScrollPane jScrollPane1 = new JScrollPane();
JTextArea Jtxa = new JTextArea();
JPanel jPanel2 = new JPanel();
JButton jButton1 = new JButton();
JButton jButton2 = new JButton();
FlowLayout flowLayout1 = new FlowLayout();
JButton jButton3 = new JButton();
Border border1 = BorderFactory.createEtchedBorder(EtchedBorder.RAISED,
Color.white, new Color(148, 145, 140));
JMenuBar jMenuBar1 = new JMenuBar();
JMenu jMenu1 = new JMenu();
JMenuItem jMenuItem1 = new JMenuItem();
JMenuItem jMenuItem2 = new JMenuItem();
JMenuItem jMenuItem3 = new JMenuItem();
public ServerMain() {
try {
jbInit();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
public void jbInit() throws Exception{
this.setSize(400,300);
jPanel1.setLayout(borderLayout1);
jButton1.setFont(new java.awt.Font(&quot;Dialog&quot;, 0, 12));
jButton1.setText(&quot;退出&quot;);
jButton2.setFont(new java.awt.Font(&quot;Dialog&quot;, 0, 12));
jButton2.setText(&quot;清空记录&quot;);
jPanel2.setLayout(flowLayout1);
flowLayout1.setAlignment(FlowLayout.RIGHT);
Jtxa.setBackground(Color.white);
Jtxa.setText(&quot;&quot;);
Jtxa.setLineWrap(true);
jButton3.setFont(new java.awt.Font(&quot;Dialog&quot;, 0, 12));
jButton3.setText(&quot;保存记录&quot;);
jPanel1.setBorder(null);
jScrollPane1.setBorder(border1);
this.setJMenuBar(jMenuBar1);
jMenu1.setText(&quot;File&quot;);
jMenuItem1.setActionCommand(&quot;Config Directory&quot;);
jMenuItem1.setText(&quot;Config Directory&quot;);
jMenuItem1.addActionListener(new ServerMain_jMenuItem1_actionAdapter(this));
jMenuItem2.setFont(new java.awt.Font(&quot;Dialog&quot;, Font.PLAIN, 12));
jMenuItem2.setText(&quot;Config Logon&quot;);
jMenuItem2.addActionListener(new ServerMain_jMenuItem2_actionAdapter(this));
jMenuItem3.setFont(new java.awt.Font(&quot;Dialog&quot;, Font.PLAIN, 12));
jMenuItem3.setText(&quot;Exit&quot;);
jMenuItem3.addActionListener(new ServerMain_jMenuItem3_actionAdapter(this));
this.getContentPane().add(jPanel1, BorderLayout.CENTER);
jPanel1.add(jScrollPane1, BorderLayout.CENTER);
jPanel1.add(jPanel2, BorderLayout.SOUTH);
jPanel2.add(jButton3, null);
jPanel2.add(jButton2, null);
jPanel2.add(jButton1, null);
jScrollPane1.getViewport().add(Jtxa, null);
jMenuBar1.add(jMenu1);
jMenu1.add(jMenuItem1);
jMenu1.addSeparator();
jMenu1.add(jMenuItem2);
jMenu1.add(jMenuItem3);

profile=new Properties();

File itfile=new File(&quot;Server.info&quot;);
if (!itfile.exists() ||itfile.isDirectory()||!itfile.canRead()) {
dir=&quot;.&quot;;
}else{
proFin=new FileInputStream(itfile);
profile.load(proFin);
dir=profile.getProperty(&quot;dir&quot;);
}


}

public String[] getFileName() {
File directory=new File(dir);

if (directory.exists()&&directory.canRead() && directory.isDirectory()){
return directory.list();
}

return null;
}

public byte[] transferFile(String fileName,String name,String pass) {
//*************权限判定****************
privilege=new Properties();
try {
File priFile=new File(&quot;privliege.info&quot;);
if (!priFile.exists() || !priFile.canRead()||priFile.isDirectory()){
Jtxa.append(&quot;错误:权限文件可能不存在或者文件不可读,请重新设置权限文件!/n&quot;);
return null;
}
priFin = new FileInputStream(priFile);
privilege.load(priFin);
if (privilege.getProperty(name)!=pass)
{
Jtxa.append(&quot;错误:密码不正确,或者无此用户名,请求驳回!/n&quot;);
return null;
}

//无此用户或密码无效返回空值
}
catch (IOException ex2) {ex2.printStackTrace();
}
//*************权限判定结束****************

File file=new File(fileName);
if (file.exists()&&file.canRead() && !file.isDirectory()){
FileInputStream fin = null;
try {
fin = new FileInputStream(file);

FileChannel rochannel=fin.getChannel();
ByteBuffer robuf=rochannel.map(FileChannel.MapMode.READ_ONLY,0,rochannel.size());
byte buff[]=new byte[robuf.capacity()];
robuf.get(buff,0,buff.length);
Jtxa.append(&quot;信息:用户 &quot;+name+&quot;开始读取文件&quot;+fileName+&quot;. 时间: &quot;+new Date().toString()+&quot; . /n&quot;);
return buff;
}
catch (IOException ex) {
Jtxa.append(&quot;错误:用户 &quot;+name+&quot;读取文件&quot;+fileName+&quot;失败. 时间: &quot;+new Date().toString()+&quot; . /n&quot;);
ex.printStackTrace();
}
}
return null;
}

public static void main(String[] args){
ServerMain frame=new ServerMain();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
try {
TransferInter stub=(TransferInter)java.rmi.server.UnicastRemoteObject.exportObject(frame,0);
java.rmi.registry.LocateRegistry.createRegistry(1099);
java.rmi.registry.LocateRegistry.getRegistry().rebind(&quot;Transfer&quot;,stub);
System.out.println(&quot;Success binding the remote object&quot;);
System.out.println(&quot;Server Ready!&quot;);
}
catch (Exception ex) {
ex.printStackTrace();
}

}

public void jMenuItem1_actionPerformed(ActionEvent actionEvent) {
new configDir().setVisible(true);
}

public void jMenuItem2_actionPerformed(ActionEvent actionEvent) {
new Privilege().setVisible(true);
}

public void jMenuItem3_actionPerformed(ActionEvent actionEvent) {
System.exit(0);
}

}

class ServerMain_jMenuItem3_actionAdapter
implements ActionListener {
private ServerMain adaptee;
ServerMain_jMenuItem3_actionAdapter(ServerMain adaptee) {
this.adaptee = adaptee;
}

public void actionPerformed(ActionEvent actionEvent) {
adaptee.jMenuItem3_actionPerformed(actionEvent);
}
}

class ServerMain_jMenuItem2_actionAdapter
implements ActionListener {
private ServerMain adaptee;
ServerMain_jMenuItem2_actionAdapter(ServerMain adaptee) {
this.adaptee = adaptee;
}

public void actionPerformed(ActionEvent actionEvent) {
adaptee.jMenuItem2_actionPerformed(actionEvent);
}
}

class ServerMain_jMenuItem1_actionAdapter
implements ActionListener {
private ServerMain adaptee;
ServerMain_jMenuItem1_actionAdapter(ServerMain adaptee) {
this.adaptee = adaptee;
}
public void actionPerformed(ActionEvent actionEvent) {
adaptee.jMenuItem1_actionPerformed(actionEvent);
}
}
 
代码我会好看看一下,先谢谢 wanchi

观注一下其它方案和想法
 
http://www.indyproject.org/Sockets/Demos/index.en.iwp
你到这下载一个demo试一下吧
 
问题解决了,现在在试一个上传本地含子文件夹的文件夹到FTP,递归还没做好,
各位可有好的想法!

散分了
 
后退
顶部