文件传输

文件传输

前面的案例都是传输字符串.还有一种常见的情况,就是在服务端和客户端之间传输文件.

计入,客户端显示了一个菜单:当输入S1,S2或S3时,分别向服务端发送文件Client01.jpg,Client02.jpg,Client02.jpg;当输入R1,R2或R3时,分别从服务端接受文件Server01.jpg,Server02.jpg,Server03.jpg.那么,如何完成这项功能呢?

 

方法1:类似FTP协议,服务端监听两个端口:一个称为控制端口,用于接受各种命令字符串(只是接受或发送文件);一个称为数据端口,用于传输实际数据,就是发送和接收文件

 

方法2:服务端只监听一个端口,用于接受来自客户端的命令字符串,称为控制端口.客户端在发出命令字符串之前,先开辟一个本地端口专用于收发文件,然后向服务端发送命令字符串,其中包含了客户端专用于收发数据的端口号.服务端接收到请求之后,连接至客户端专用于收发文件的端口,然后传输数据,结束后关闭连接.

现在只关注两种方式中的数据端口,当使用方法1的时候,服务端的数据端口需要同时为多个客户端的多次请求服务,因此需要采用异步方式;使用方法2时,服务端与客户端在每次传输数据时都会重新建立新的连接,在传输完成后立即关闭,因此在数据端口上传输文件时不需要采用异步方式.但是在控制端口仍然需要使用异步方式.

咱们使用方法2来实现文件的接受.

订立协议

1.发送文件

先看一下发送文件的情况:如果要将Client01.jpg由客户端发往服务端,可以归纳为以下几个步骤:

(1).客户端对端口进行监听,假设端口号为8005.

(2).假设客户输入了S1,则发送下面的控制字符串到服务端:[file=Client01.jpg,mode=send.port=8005].

(3)服务端收到以后,根据客户端IP和端口号与该客户端建立连接

(4)客户端向网络流羞辱数据,开始发送文件.

(5)传送完毕之后客户端和服务端关闭数据端口的连接.

类似之前的规则,订立的发布文件协议可以为:[file=Client01.jpg,mode=send,port=8005].但是,由于他是一个普通的字符串,在前面我们采用了正则表达式的方法来获得其中的有效值,但还有更好地办法----使用XML.对于上面的语句,我们可以写成这样的XML:

<protocol><file name=”Client01.jpg” mode=senf,port=”8005” /></protocol>

这样处理起来就会方便多了,因为处理XML格式有更丰富的类型支持.接下来看一下接收文件的流程及其协议.

2.接收文件

接收文件与发送文件实际上完全类似,区别只是:当发送文件时,由客户端向网络流写入数据;当接收文件时,由服务端想网络流介入数据.接受文件的步骤如下:

(1).客户端对端口进行监听,假设端口号为8006.

(2).假设客户端输入了R1,则发送控制字符串:<protocol><file name=”Server01.jpg” mode=”receive” port=”8006”/></protocol>到服务端.

(3).服务端接收到以后,根据客户端IP和端口号与该客户端建立连接.

(4).服务端向网络流写入数据,开始发送文件.

(5).传送完毕后客户端和服务端关闭数据端口的连接.

协议处理类的实现

在开始编写实际的服务端客户端代码之前,首先要编写处理协议的类,这个类需要两个功能:一是方便获取完整的协议信息,因为前面说过,服务端可能将客户端的多次独立请求拆分或合并.比如,客户端连续发送了两条控制信息到服务端,而服务端将它们合并了,则需要先拆开再分别处理.二是方便获取节点信息,因为协议是XML格式,所以还需要一个类专门对XML进行处理,获得节点的值.

1.ProtocolHandler辅助类

先看下ProtocolHandler,它与前面说过的ResquestHandler作用相同.需要注意的是必须将它声明为实例的,而非静态的,这是因为每个TcpClient都需要对应一个ProtocolHandler,它内部维护的partialProtocol不能共享,在协议发送不完整的情况下,这个变量用于临时保存被截断的字符串.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Server
{
    public class ProtocolHandler
    {
        private string partialProtocol;//保存不完整的协议
        public ProtocolHandler()
        {
            partialProtocol = "";
        }
        public string[] GetProtocol(string input)
        {
            return GetProtocol(input,null);
        }
        //获得协议
        private string[] GetProtocol(string input, List<string>outputList)
        {
            if (outputList==null)
            {
                outputList = new List<string>();
            }
            if (string.IsNullOrEmpty(input))
            {
                return outputList.ToArray();
            }
            if (!string.IsNullOrEmpty(partialProtocol))
            {
                input = partialProtocol + input;
            }

            string pattern = "(^<protocol>.*?</protocol>)";

            //如果有匹配,说明已经找到了,是完整的协议
            if (Regex.IsMatch(input,pattern))
            {
                //获取匹配的值
                string match = Regex.Match(input,pattern).Groups[0].Value;
                outputList.Add(match);
                partialProtocol = "";

                //缩短input的长度
                input = input.Substring(match.Length);

                //递归调用
                GetProtocol(input,outputList);
            }

            else
            {
                //如果不匹配,说明协议长度不够
                //那么先缓存,然后等待下一次请求
                partialProtocol = input;
            }
            return outputList.ToArray();
        }
    }
}

因为这个类不是重点,这里贴下代码就够了.

2.FileRequestType枚举类型和FileProtocol结构

因为XML是以字符串的形式进行传输,为了方便使用,最好构建一个强类型对它们进行操作,这样会方便很多.首先可以定义FileRequestMode枚举类型,用来表示是发送文件还是接受文件:

    public enum FileRequestMode
    {
        Send=0,
        Receive
    }

接下来再定义一个FileProtocol结构,用来为整个协议字符串提供强类型的访问,注意这里覆盖了基类的ToString()方法,这样在客户端就不需要再手工去编写XML,只要在FileProtocol结构值上调用ToString()就行了:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Server
{
    public struct FileProtocol
    {
        private readonly FileRequestMode mode;
        private readonly int port;
        private readonly string fileName;

        public FileProtocol(FileRequestMode mode, int port, string fileName)
        {
            this.mode = mode;
            this.port = port;
            this.fileName = fileName;
        }
        public FileRequestMode Mode { get { return mode; } }

        public int Port
        {
            get
            {
                return port;
            }
        }

        public string FileName
        {
            get
            {
                return fileName;
            }
        }

        public override string ToString()
        {
            return string.Format("<protocol><file name=\"{0}\" mode=\"{1}\" port=\"{2}\"/></protocol>",fileName,mode,port);
        }
    }
}

3.ProtocolHelper辅助类

这个类专用于将XML格式的协议映射为上面定义的强类型对象,这里没有加入try/catch异常处理,因为协议对用户来说是不可见的,而客户端应该总是发送正确的协议:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Server
{
    public class ProtocolHelper
    {
        private XmlNode fileNode;
        private XmlNode root;

        public ProtocolHelper(string protocol)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(protocol);
            root = doc.DocumentElement;
            fileNode = root.SelectSingleNode("file");
        }

        //此时的protocol已定位单条完整的protocol
        private FileRequestMode GetFileMode()
        {
            string mode = fileNode.Attributes["mode"].Value;
            mode = mode.ToLower();
            if (mode=="send")
            {
                return FileRequestMode.Send;
            }
            else
            {
                return FileRequestMode.Receive;
            }
        }

        //获取单条协议包含的信息
        public FileProtocol GetProtocol()
        {
            FileRequestMode mode = GetFileMode();
            string fileName = "";
            int port = 0;
            fileName = fileNode.Attributes["name"].Value;
            port = Convert.ToInt32(fileNode.Attributes["port"].Value);

            return new FileProtocol(mode,port,fileName);
        }
    }
}

关于XML部分的内容,我们会详细讲解.

客户端发送文件

我们还是讲一个问题分为两部分来处理:先是客户端发送文件,然后是服务端接收文件.

1.客户端的实现

不着急实现客户端S1,R1等用户菜单,首先完成发送文件这一功能为前面的Client类再添加一个SendFile()方法.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Threading;
using System.IO;
using Server;
namespace Client
{
    public class Client
    {
        private const int BufferSize = 8192;
        private byte[] buffer;
        private TcpClient client;
        private NetworkStream streamToServer;

        public Client()
        {
            try
            {
                client = new TcpClient();
                client.Connect("192.168.3.19",8500);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
            buffer = new byte[BufferSize];

            //打印连接到的服务器信息
            Console.WriteLine("Server Connected! Local: {0}-->Server:{1}",client.Client.LocalEndPoint,client.Client.RemoteEndPoint);
            streamToServer = client.GetStream();
        }

        //发送消息到服务器
        public void SendMessage(string msg)
        {
            byte[] temp = Encoding.Unicode.GetBytes(msg);//获得缓存
            try
            {
                streamToServer.Write(temo,0,temp.Length);
                Console.WriteLine("Sent: {0}", msg);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }

        //发送文件--异步方法
        public void BeginSendFile(string filePath)
        {
            ParameterizedThreadStart start = new ParameterizedThreadStart(BeginSendFile);
            start.BeginInvoke(filePath,null,null);
        }

        private void BeginSendFile(object obj)
        {
            string filePath = obj as string;
            SendFile(filePath);
        }
        //发送文件
        public void SendFile(string filePath)
        {
            IPAddress ip = IPAddress.Parse("192.168.3.19");
            TcpListener listener = new TcpListener(ip,0);
            listener.Start();

            //获取本地监听的端口号
            IPEndPoint endPoint = listener.LocalEndpoint as IPEndPoint;
            int listeningPort = endPoint.Port;

            //获取发送的协议字符串
            string fileName = Path.GetFileName(filePath);
            FileProtocol protocol = new FileProtocol(FileRequestMode.Send,listeningPort,fileName);
            string pro = protocol.ToString();

            SendMessage(pro);//发送协议到服务端

            //中断,等待远程连接
            TcpClient localClient = listener.AcceptTcpClient();
            Console.WriteLine("Start sending file...");
            NetworkStream stream = localClient.GetStream();

            //创建文件流
            FileStream fs = new FileStream(filePath,FileMode.Open,FileAccess.Read);

            byte[] fileBuffer = new byte[1024];
            //每次传输1KB

            int bytesRead;
            int totalBytes = 0;

            //创建获取文件发送状态的类
            SendStatus status = new SendStatus();

            //将文件流转写入网络流
            try
            {
                do
                {
                    Thread.Sleep(10);//模拟远程传输视觉效果,暂停10秒
                    bytesRead = fs.Read(fileBuffer, 0, fileBuffer.Length);
                    stream.Write(fileBuffer, 0, bytesRead);
                    totalBytes += bytesRead;
                    status.PrintStatus(totalBytes);
                } while (bytesRead > 0);
                Console.WriteLine("Total {0} bytes sent ,Done!", totalBytes);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                stream.Dispose();
                fs.Dispose();
                localClient.Close();
                listener.Stop();
            }
        }
    }
}
 

SendStatus类:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Client
{
    public class SendStatus
    {
        private FileInfo info;
        private long fileBytes;

        public SendStatus(string filePath)
        {
            info = new FileInfo(filePath);
            fileBytes = info.Length;
        }

        public void PrintStatus(int sent)
        {
            string percent = GetPercent(sent);
            Console.WriteLine("Sending {0} bytes, {1}% ...",sent,percent);
        }
        //获得文件发送的百分比
        private string GetPercent(int sent)
        {
            decimal allBytes = Convert.ToDecimal(fileBytes);
            decimal currentSent = Convert.ToDecimal(sent);
            decimal percent = (currentSent / allBytes) * 100;

            percent = Math.Round(percent,1);//保留一位小数

            if (percent.ToString()=="100.0")
            {
                return "100";
            }
            else
            {
                return percent.ToString();
            }
        }
    }
}
 

主程序:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            ConsoleKey key;
            Client c = new Client();
            string filePath = Environment.CurrentDirectory + "/" + "Client01.jpg";
            if (File.Exists(filePath))
            {
                c.BeginSendFile(filePath);
            }
            Console.WriteLine("\n\n按Q退出");
            do
            {
                key = Console.ReadKey(true).Key;
            } while (key!=ConsoleKey.Q);
        }
    }
}
 

这段代码游侠买几个地方需要注意:

1.)在Main()方法中可以看到,图片的位置为应用程序所在的目录.如果处于调试模式,那么在项目的Bin目录下的Debug目录中防止三种图片Client01.jpg,Client02.jpg,Client03.jpg,作为测试目的.

2.)客户端提供了一个SendFile()和两个BeginSendFile()方法,分别用于同步和异步传输,其中私有的BeginSendFile()方法只是个辅助方法,实际上对于发送文件这样的操作,集合总是需要使用异步方式.

3.)另外编写了一个SendStatus类,用来记录和打印完成的状态,已经发送了多少字节.

2.服务端的实现

服务端要完成的就是解析协议,连接至客户端,根据协议内容,判断时发送文件还是接收文件,下面是代码部分:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Server
{
    public class Server
    {
        private TcpClient client;
        private NetworkStream streamToClient;
        private const int BufferSize = 8192;
        private byte[] buffer;
        private ProtocolHandler handler;

        public Server(TcpClient client)
        {
            this.client = client;

            //打印连接到的客户端信息
            Console.WriteLine("ClientConnected! Local :{0}<--Client: {1}",client.Client.LocalEndPoint,client.Client.RemoteEndPoint);

            //获得流
            streamToClient = client.GetStream();
            buffer = new byte[BufferSize];

            handler = new ProtocolHandler();

        }

        //开始进行读取
        public void BeginRead()
        {
            AsyncCallback callBack = new AsyncCallback(OnReadComplete);
            streamToClient.BeginRead(buffer,0,BufferSize,callBack,null);
        }
        //读取完成时进行回调
        private void OnReadComplete(IAsyncResult ar)
        {
            int bytesRead = 0;
            try
            {
                bytesRead = streamToClient.EndRead(ar);
                Console.WriteLine("Reading data,{0} bytes...",bytesRead);
                if (bytesRead==0)
                {
                    Console.WriteLine("Client offline.");
                    return;
                }
                string msg = Encoding.Unicode.GetString(buffer,0,bytesRead);
                Array.Clear(buffer,0,buffer.Length);//清空缓存,避免脏读

                //获取protocol数组
                string[] protocolArray = handler.GetProtocol(msg);
                foreach (string pro in protocolArray)
                {
                    //这里异步调用,不然这里会比较耗时
                    ParameterizedThreadStart start = new ParameterizedThreadStart(handleProtocol);
                    start.BeginInvoke(pro,null,null);
                }
                //再次调用BeginRead(),完成时调用自身,形成无限循环
                AsyncCallback callBack = new AsyncCallback(OnReadComplete);
                streamToClient.BeginRead(buffer,0,BufferSize,callBack,null);
            }
            catch (Exception ex)
            {
                if (streamToClient!=null)
                {
                    streamToClient.Dispose();
                }
                client.Close();
                Console.WriteLine(ex.Message);
            }
        }
        //处理protocol
        private void handleProtocol(object obj)
        {
            string pro = obj as string;
            ProtocolHelper helper = new ProtocolHelper(pro);
            FileProtocol protocol = helper.GetProtocol();

            if (protocol.Mode==FileRequestMode.Send)
            {
                //客户端发送文件,对服务端来说则是接收文件
                receiveFile(protocol);
            }
            else if (protocol.Mode==FileRequestMode.Receive)
            {
                //客户端接收文件,对服务端来说是发送文件
                //sendFile(protocol);
            }
        }
        //接收文件
        private void receiveFile(FileProtocol protocol)
        {
            //获取远程客户端的位置
            IPEndPoint endPoint = client.Client.RemoteEndPoint as IPEndPoint;
            IPAddress ip = endPoint.Address;

            //使用新端口,获得远程用于接收文件的端口
            endPoint = new IPEndPoint(ip,protocol.Port);

            //连接到远程客户端
            TcpClient localClient;
            try
            {
                localClient = new TcpClient();
                localClient.Connect(endPoint);
            }
            catch (Exception ex)
            {
                Console.WriteLine("无法连接到客户端 --> {0}",endPoint);
                return;
            }

            //获取发送文件的流
            NetworkStream streamToCLient = localClient.GetStream();

            //随机生成一个在当前目录下的文件名称
            string path = Environment.CurrentDirectory + "/" + generateFileName(protocol.FileName);

            byte[] fileBuffer = new byte[1024];//每次收1KB
            FileStream fs = new FileStream(path,FileMode.CreateNew,FileAccess.Write);

            //从缓存Buffer中读入到文件流中
            int bytesRead;
            int totalBytes = 0;
            do
            {
                bytesRead = streamToCLient.Read(buffer,0,BufferSize);

                fs.Write(buffer, 0, bytesRead);
                totalBytes += bytesRead;
                Console.WriteLine("Receiving {0} bytes ...",totalBytes);
            } while (bytesRead>0);
            Console.WriteLine("Total {0} bytes received,Done! ",totalBytes);

            streamToClient.Dispose();
            fs.Dispose();
            localClient.Close();
        }
        //随机获取一个图片名称
        private string generateFileName(string fileName)
        {
            DateTime now = DateTime.Now;
            return string.Format("{0}_{1}_{2}_{3}",now.Minute,now.Second,now.Millisecond,fileName);
        }
    }
}
 

主程序如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Server
{
    class Program
    {
        static void Main(string[] args)
        {

            Console.WriteLine("Server is running...");
            IPAddress ip = IPAddress.Parse("192.168.1.113");
            TcpListener listener = new TcpListener(ip,8500);
            listener.Start();
            Console.WriteLine("Start Listening...");
            while (true)
            {
                //获取一个连接,同步方法,在此处中断
                TcpClient client = listener.AcceptTcpClient();
                Server wapper = new Server(client);
                wapper.BeginRead();
            }
        }
    }
}
 

这段代码需要注意这么几点:

1.在OnReadComplete()回调方法的foreach循环中,使用委托异步调用了handlerProtocol()方法,这是因为handlerProtocol即即将执行的是一个读取或接收文件的操作,也就是一个相对耗时的操作.

2.在handlerProtocol()方法中,可以体会到定义ProtocolHelper类和FileProtocol结构的好处,如果不定义它们,这里将是杂乱的处理XML以及类型转换的代码.

3.handlerProtocol()方法中进行了一个条件判断,注意sendFile()被屏蔽了,这里还没有为服务单发送文件至客户端.

4.receiveFile()方法是实际接受客户端发来文件的方法,这里没有什么特别之处.需要注意的是文件存储的路径,它保存在了当前程序执行的目录下,文件的名称使用GetFileName()方法生成一个与时间有关的随机名称.

最后我想说一点,因为楼主中途换个一个教室,程序怎么都出错,结果搞了半天发现是IP地址出了问题,每个教室的IP地址可能不同,还有一点需要注意,别忘了添加对解决方案的引用,要不然会报错.

 

不管怎么说,程序算是完成了,楼主这里用了一个40M大小的文件进行测试(原本是一个avi,楼主改了一下后缀名)....程序是如此的慢,为啥呢?因为咱们一次只传输1KB...

到现在为止,咱们关于网络编程的内容算是搞一个段落了,开头第一部分讲解了TCP协议,套接字,即时通信程序三种开发模式,以及两个基本操作----监听端口和连接远程服务器.

第二部分是一个简单的实例:从客户端传输字符串到服务器,服务器接受并处理字符串,在将处理过的字符串发回给客户端.

第三部分是异步传输和文本边界,这是对第二部分的强化.

第四部分是发送文件.

时间: 2024-10-11 05:08:01

文件传输的相关文章

微信文件传输助手文件夹在哪?一起来找找

微信文件传输助手是微信电脑版与手机微信之间相互传输图片等文件的好工具,但很多童鞋都找不到微信文件传输助手文件夹在哪,就让我们一起找找吧 1.先说说手机微信文件传输助手文件夹在哪吧 文件夹路径为/Tencent/MicroMsg/Download/ 2.电脑版微信文件传输助手文件夹在:/微信安装保存目录/wechat files/微信号/ 也可以点击接收到的图片下载保存到相应位置即可

详解“FTP文件传输服务”安装配置实例

"FTP文件传输服务"安装配置实例 家住海边喜欢浪:zhang789.blog.51cto.com 目录 简介 ftp工作原理 常见的FTP服务 Vsftpd服务器的安装 Vsftpd.conf配置文件详解 配置FTP服务器实例 实例:配置匿名用户 实例:配置本地用户登录 实例:配置虚拟用户登录(MySQL认证) 实例:控制用户登录 实例:设置欢迎信息 分析vsftpd日志管理 FTP服务器配置与管理 简介 FTP 是File Transfer Protocol(文件传输协议)的英文简

linux网络环境下socket套接字编程(UDP文件传输)

今天我们来介绍一下在linux网络环境下使用socket套接字实现两个进程下文件的上传,下载,和退出操作! 在socket套接字编程中,我们当然可以基于TCP的传输协议来进行传输,但是在文件的传输中,如果我们使用TCP传输,会造成传输速度较慢的情况,所以我们在进行文件传输的过程中,最好要使用UDP传输. 在其中,我们需要写两个程序,一个客户端,一个服务端,在一个终端中,先运行服务端,在运行客户端,在服务端和客户端都输入IP地址和端口号,注意服务端和客户端的端口号要相同,然后选择功能,在linux

FTP文件传输协议之vsftpd服务

一.FTP服务概述 FTP(File Transfer Protocol,文件传输协议)是典型的C/S结构的应用层协议,需要由服务端软件.客户端软件共同实现文件传输功能 FTP服务器默认使用TCP协议的20.21端口与客户端实现通信.20端口用于建立数据连接,并传输数据文件:21端口用于建立控制连接,并传输FTP控制命令.FTP数据连接分为主动模式和被动模式 主动模式:服务器主动发起数据连接 被动模式:服务器被动等待数据连接 vsftpd软件 vsftpd是目前在Linux/Unix领域应用十分

运维学习之Linux系统中的文件传输、归档、压缩

不同系统之间的文件传输 1.文件归档 1. 文件归档,就是把多个文件变成一个归档文件 2. tar c ##创建 f ##指定归档文件名称 t ##显示归档文件中的内容 r ##向归档文件中添加文件 --get ##取出单个文件 --delete ##删除单个文件 x ##取出归档文件中的所有内容 -C ##指定解档目录 -z ##gz格式压缩 -j ##bz2格式压缩 -J ##xz格式压缩 2.压缩 gz gzip etc.tar ##压缩成gz格式 gunzip  etc.tar.gz #

FTP文件传输服务器(详解)

  FTP文件传输服务器 一实验目标 安装配置VSFTP 实战匿名访问VSFTP 实战用户名密码方式访问VSFTP 实战ftp虚拟帐号方式访问VSFTP   二实验环境 FTP服务端xuegod63.cn   IP192.168.1.63 FTP客户端xuegod64.cn   IP192.168.1.64   三FTP服务概述     FTP服务器File Transfer Protocol Server是在互联网上提供文件存储和访问服务的计算机它们依照FTP协议提供服务.VSFTP是一个基于

c# 局域网文件传输实例

一个基于c#的点对点局域网文件传输小案例,运行效果截图 //界面窗体 using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.IO;using System.Linq;using System.Text;using System.Threading;using System.Threading.Task

在windows 与Linux间实现文件传输(C++&amp;C实现)

要实现windows与linux间的文件传输,可以通过socket网络编程来实现. 这次要实现的功能与<Windows下通过socket进行字符串和文件传输>中实现的功能相同,即客户端首先向服务器发送一个字符串,接着发送一个文件:服务器首先接收客户端发送的字符串,作为文件名,接着接收客户端发送的文件并保存到本地. 以window平台程序作为客户端,linux平台的程序作为服务器,并且是在局域网范围内进行文件传输. windows客户端的实现: 客户端程序在VS2012 IDE下编译运行,依旧使

HTTP文件传输

HTTP协议用于文件传输时,一般把文件内容放到消息体中.作为TCP之上的流式传输协议,发送端和接收端可以对大文件进行流式的发送和接收. 1.确定大小的文件传输 消息头部的Content-Length字段表示文件的长度,用于接收端确定文件的结束. 2.Chunked编码 当文件大小无法事先确定时,无法设置Content-Length字段.此时可以用分块传输的方式,将文件分成多个部分进行发送.在分块发送方式下,头部增加Transfer-Encoding: chunked,存在这个头部时不允许再加上C

Java基于Socket文件传输示例(转)

最近需要进行网络传输大文件,于是对基于socket的文件传输作了一个初步的了解.在一位网友提供的程序基础上,俺进行了一些加工,采用了缓冲输入/输出流来包装输出流,再采用数据输入/输出输出流进行包装,加快传输的速度.废话少说,先来看服务器端的程序. 1.服务器端 package sterning; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.DataOutputStream;