搭建简单的FTP服务器

时间:2023-03-08 16:33:18

客户端部分主要使用C#提供的webclient类 (https://msdn.microsoft.com/library/system.net.webclient.aspx)

通过WebClient.UploadData()方法进行提交。

 OpenFileDialog fileDialog = new OpenFileDialog();
fileDialog.Multiselect = true;
fileDialog.Title = "请选择文件";
fileDialog.Filter = "所有文件(*xls*)|*.xls*"; //设置要选择的文件的类型
if (fileDialog.ShowDialog() == DialogResult.OK)
{
string file = fileDialog.FileName;//返回文件的完整路径
string url = "http://" + ClientSettings.Host + ":8087/upload?type=excel";
string filename = Path.GetFileName(file);
var wb = new WebClient(); var client = new HttpUpload(); string res = "";
FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read);
byte[] bytes = new byte[(int)fs.Length];
fs.Read(bytes, , bytes.Length);
fs.Close();
client.SetFieldValue("uploadfile", filename, " application/octet-stream", bytes);
client.SetFieldValue("submit", "提交");
client.Upload(url, out res);
}
 using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Net; /// <summary>
/// 用于模拟POST上传文件到服务器
/// </summary>
public class HttpUpload
{
private ArrayList bytesArray;
private Encoding encoding = Encoding.UTF8;
private string boundary = String.Empty; public HttpUpload()
{
bytesArray = new ArrayList();
string flag = DateTime.Now.Ticks.ToString("x");
boundary = "---------------------------" + flag;
} /// <summary>
/// 合并请求数据
/// </summary>
/// <returns></returns>
private byte[] MergeContent()
{
int length = ;
int readLength = ;
string endBoundary = "--" + boundary + "--\r\n";
byte[] endBoundaryBytes = encoding.GetBytes(endBoundary); bytesArray.Add(endBoundaryBytes); foreach (byte[] b in bytesArray)
{
length += b.Length;
} byte[] bytes = new byte[length]; foreach (byte[] b in bytesArray)
{
b.CopyTo(bytes, readLength);
readLength += b.Length;
} return bytes;
} /// <summary>
/// 上传
/// </summary>
/// <param name="requestUrl">请求url</param>
/// <param name="responseText">响应</param>
/// <returns></returns>
public bool Upload(String requestUrl, out String responseText)
{
WebClient webClient = new WebClient();
webClient.Headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary); byte[] responseBytes;
byte[] bytes = MergeContent(); try
{
responseBytes = webClient.UploadData(requestUrl, "POST", bytes);
responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
return true;
}
catch (WebException ex)
{
Stream responseStream = ex.Response.GetResponseStream();
responseBytes = new byte[ex.Response.ContentLength];
responseStream.Read(responseBytes, , responseBytes.Length);
}
responseText = System.Text.Encoding.UTF8.GetString(responseBytes);
return false;
} /// <summary>
/// 设置表单数据字段
/// </summary>
/// <param name="fieldName">字段名</param>
/// <param name="fieldValue">字段值</param>
/// <returns></returns>
public void SetFieldValue(String fieldName, String fieldValue)
{
string httpRow = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n";
string httpRowData = String.Format(httpRow, fieldName, fieldValue); bytesArray.Add(encoding.GetBytes(httpRowData));
} /// <summary>
/// 设置表单文件数据
/// </summary>
/// <param name="fieldName">字段名</param>
/// <param name="filename">字段值</param>
/// <param name="contentType">内容内型</param>
/// <param name="fileBytes">文件字节流</param>
/// <returns></returns>
public void SetFieldValue(String fieldName, String filename, String contentType, Byte[] fileBytes)
{
string end = "\r\n";
string httpRow = "--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string httpRowData = String.Format(httpRow, fieldName, filename, contentType); byte[] headerBytes = encoding.GetBytes(httpRowData);
byte[] endBytes = encoding.GetBytes(end);
byte[] fileDataBytes = new byte[headerBytes.Length + fileBytes.Length + endBytes.Length]; headerBytes.CopyTo(fileDataBytes, );
fileBytes.CopyTo(fileDataBytes, headerBytes.Length);
endBytes.CopyTo(fileDataBytes, headerBytes.Length + fileBytes.Length); bytesArray.Add(fileDataBytes);
}
}

服务器部分,搭建一个简单的web服务,接收POST请求即可.

下例是用GO写的一个简单的接收示例

 func uploadHandler(res http.ResponseWriter, req *http.Request) {
switch req.Method {
case "POST":
{
ftype := req.FormValue("type")
if ftype == "excel" {
err := req.ParseMultipartForm()
if err != nil {
return
} httpDoc := "/../../../Excels/"
m := req.MultipartForm files := m.File["uploadfile"]
for i, _ := range files {
file, err := files[i].Open()
defer file.Close()
if err != nil {
return
} tmp := strings.Split(files[i].Filename, "\\")
if len(tmp) <= {
tmp = strings.Split(files[i].Filename, "/")
if len(tmp) <= {
return
}
} filename := tmp[len(tmp)-]
if filename == "" {
return
} dst, err := os.Create(httpDoc + filename)
defer dst.Close()
if err != nil {
return
} if _, err := io.Copy(dst, file); err != nil {
return
}
}
}
}
}
} type PublishServer struct { }
var serverm *PublishServer func PublishServer_GetMe() *PublishServer {
if serverm == nil {
serverm = &PublishServer{}
serverm.Derived = serverm
}
return serverm
} func (this *PublishServer) Init() bool {
// 启动http服务
StartHttpServer() return true
} func (this *PublishServer) MainLoop() {
time.Sleep(time.Millisecond * )
} func StartHttpServer() {
// 读取JSON配置
httpProt := env.Get("publish", "httpport")
httpDoc := env.Get("publish", "httpdoc") http.Handle("/", http.FileServer(http.Dir(httpDoc)))
http.Handle("/excels/", http.StripPrefix("/excels/", http.FileServer(http.Dir(httpDoc+"/../../../Excels/"))))
http.HandleFunc("/upload", uploadHandler) go http.ListenAndServe(httpProt, nil)
}

Web页面

 <html>
<body>
<h1> 上传页面 </h1>
<form name="uploadForm" method="POST"
enctype="multipart/form-data"
action="/upload?type=excel">
<b>Upload File:</b>
<br>
<input type="file" name="uploadfile" size=""/>
<br>
<input type="submit" name="submit" value="提交">
<input type="reset" name="reset" value="重置">
</form>
</body>
</html>