码迷,mamicode.com
首页 > 其他好文 > 详细

Socket发送文件

时间:2017-05-31 14:17:09      阅读:287      评论:0      收藏:0      [点我收藏+]

标签:ret   isp   字节数组   network   cte   pos   time   start   line   

1.Net.cs
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 SocketIM
{
    ////// Net : 提供静态方法,对常用的网络操作进行封装
    public  class Net
    {
        private Net()
        {
        }


        ////// 向远程主机发送数据
        //////要发送数据且已经连接到远程主机的 Socket///待发送的数据///发送数据的超时时间,以秒为单位,可以精确到微秒///0:发送数据成功;-1:超时;-2:发送数据出现错误;-3:发送数据时出现异常////// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
        public static int SendData(Socket socket, byte[] buffer, int outTime)
        {
            if (socket == null || socket.Connected == false)
            {
                throw new ArgumentException("参数socket 为null,或者未连接到远程计算机");
            }
            if (buffer == null || buffer.Length == 0)
            {
                throw new ArgumentException("参数buffer 为null ,或者长度为 0");
            }

            int flag = 0;
            try
            {
                int totalLen = buffer.Length;
                int sndLen = 0;

                while (true)
                {
                    if ((socket.Poll(outTime * 100, SelectMode.SelectWrite) == true))
                    {        // 收集了足够多的传出数据后开始发送
                        sndLen = socket.Send(buffer, sndLen, totalLen, SocketFlags.None);
                        totalLen -= sndLen;
                        if (totalLen == 0)
                        {                                        // 数据已经全部发送
                            flag = 0;
                            break;
                        }
                        else
                        {
                            if (sndLen > 0)
                            {                                    // 数据部分已经被发送continue;
                            }
                            else
                            {                                                // 发送数据发生错误
                                flag = -2;
                                break;
                            }
                        }
                    }
                    else
                    {                                                        // 超时退出
                        flag = -1;
                        break;
                    }
                }
            }
            catch (SocketException e)
            {

                flag = -3;
            }
            return flag;
        }


        ////// 向远程主机发送文件
        //////要发送数据且已经连接到远程主机的 socket///待发送的文件名称///文件发送时的缓冲区大小///发送缓冲区中的数据的超时时间///0:发送文件成功;-1:超时;-2:发送文件出现错误;-3:发送文件出现异常;-4:读取待发送文件发生错误////// 当 outTime 指定为-1时,将一直等待直到有数据需要发送
        public static int SendFile(string ip,int port, string fileName, int maxBufferLength, int outTime)
        {
            IPAddress address = IPAddress.Parse("127.0.0.1");
            IPEndPoint endpoint = new IPEndPoint(address, 11000);
            //创建服务端负责监听的套接字,参数(使用IPV4协议,使用流式连接,使用TCO协议传输数据)
            Thread.Sleep(1500);
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(endpoint);
            if (socket.Connected)
            {
                Console.WriteLine(socket.RemoteEndPoint + "连接成功");
            }
            if (fileName == null || maxBufferLength <= 0)
            {
                throw new ArgumentException("待发送的文件名称为空或发送缓冲区的大小设置不正确.");
            }
            int flag = 0;
            try
            {
                FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
                long fileLen = fs.Length;                        // 文件长度
                long leftLen = fileLen;                            // 未读取部分
                int readLen = 0;                                // 已读取部分
                byte[] buffer = null;

                if (fileLen <= maxBufferLength)
                {            /* 文件可以一次读取*/
                    buffer = new byte[fileLen];
                    readLen = fs.Read(buffer, 0, (int)fileLen);
                    flag = SendData(socket, buffer, outTime);
                }
                else
                {
                    /* 循环读取文件,并发送 */
                    while (leftLen != 0)
                    {
                        if (leftLen < maxBufferLength)
                        {
                            buffer = new byte[leftLen];
                            readLen = fs.Read(buffer, 0, Convert.ToInt32(leftLen));
                        }
                        else
                        {
                            buffer = new byte[maxBufferLength];
                            readLen = fs.Read(buffer, 0, maxBufferLength);
                        }
                        if ((flag = SendData(socket, buffer, outTime)) < 0)
                        {
                            break;
                        }
                        leftLen -= readLen;
                    }
                }
                fs.Flush();
                fs.Close();
            }
            catch (IOException e)
            {

                flag = -4;
            }
            if (flag == 0)
            {
                Console.WriteLine(fileName + "文件发送成功");
                socket.Close();
                Console.WriteLine("连接关闭");
            }
            else
            {
                Console.WriteLine(fileName + "文件发送失败,i=" + flag);
            }
            return flag;
        }
        private static void WatchConnecting()
        {
            while (true)//持续不断的监听客户端的请求            
            {
                //开始监听 客户端连接请求,注意:Accept方法,会阻断当前的线程
                Socket connection = socketWatch.Accept();
                if (connection.Connected)
                {

                    //创建通信线程
                    Thread thradRecMsg = new Thread(RecMsg);
                    thradRecMsg.IsBackground = true;
                    thradRecMsg.Start(connection);

                }
            }

        }
        ////// 接收消息
        private static void RecMsg(object socketClientPara)
        {
            string fileName = $@"d:HQ.dat";//获得用户保存文件的路径
            Socket socketClient = socketClientPara as Socket;
            FileStream fs = null;
            while (true)
            {
                //定义一个接受用的缓存区(100M字节数组)
                //将接收到的数据存入arrMsgRec数组,并返回真正接受到的数据的长度   
                if (socketClient.Connected)
                {
                    try
                    {
                        //因为终端每次发送文件的最大缓冲区是512字节,所以每次接收也是定义为512字节
                        byte[] buffer = new byte[512];
                        int size = 0;
                        //统计实际文件大小
                        long len = 0;


                        //创建文件流,然后让文件流来根据路径创建一个文件
                        fs = new FileStream(fileName, FileMode.Append);
                        //从终端不停的接受数据,然后写入文件里面,只到接受到的数据为0为止,则中断连接
                        DateTime oTimeBegin = DateTime.Now;

                        while ((size = socketClient.Receive(buffer, 0, buffer.Length, SocketFlags.None)) > 0)
                        {
                            fs.Write(buffer, 0, size);
                            len += size;
                        }
                        DateTime oTimeEnd = DateTime.Now;
                        TimeSpan oTime = oTimeEnd.Subtract(oTimeBegin);
                        fs.Flush();
                        fs.Close();
                        socketClient.Close();
                        Console.WriteLine("文件保存成功:" + fileName);
                        Console.WriteLine("接收文件用时:" + oTime.ToString() + ",文件大小:" + len / 1024 + "kb");
                    }
                    catch (Exception ex)
                    {
                        if (fs != null)
                        {
                            fs.Dispose();
                        }
                        if (File.Exists(fileName))
                        {
                            File.Delete(fileName);
                        }
                        Console.WriteLine(socketClient.RemoteEndPoint + "下线了");

                        break;
                    }
                }
                else
                {

                }
            }
        }
        private static Thread threadWatch = null;
        private static Socket socketWatch = null;
        public static void AcceptFile(string ip, int port, string fileName)
        { //创建服务端负责监听的套接字,参数(使用IPV4协议,使用流式连接,使用Tcp协议传输数据)
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //获取Ip地址对象
            IPAddress address = IPAddress.Parse("127.0.0.1");
            //创建包含Ip和port的网络节点对象
            IPEndPoint endpoint = new IPEndPoint(address, 11000);
            //将负责监听的套接字绑定到唯一的Ip和端口上          
            socketWatch.Bind(endpoint);
            //设置监听队列的长度
            socketWatch.Listen(10);
            connectDone.Set();
            //创建负责监听的线程,并传入监听方法
            threadWatch = new Thread(WatchConnecting);
            threadWatch.IsBackground = true;//设置为后台线程
            threadWatch.Start();//开始线程

        }
        public static void CloseTcpSocket()
        {

            threadWatch.Abort();
            socketWatch.Close();
            Console.WriteLine("服务器关闭监听");
        }
        public static ManualResetEvent connectDone = new ManualResetEvent(false);
        public static void FileMove(string ip, int port, string fromPath,string toPath)
        {

            AcceptFile(ip,port, toPath);
            connectDone.WaitOne();
            int i = SendFile(ip, port, fromPath, 512, 10000);
            Console.WriteLine("文件从"+fromPath+""+toPath+"移动成功!!!!");
        }

    }
}

2. 发送代码
   private void button1_Click(object sender, EventArgs e)
        {
            string topath = $@"d:HQ.dat";
            string frompath = $@"e:\HQ.dat";
            Net.FileMove("127.0.0.1", 11000, frompath,topath);
        }
       

 

Socket发送文件

标签:ret   isp   字节数组   network   cte   pos   time   start   line   

原文地址:http://www.cnblogs.com/kexb/p/6923437.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!