zoukankan      html  css  js  c++  java
  • Socket传输大文件(发送与接收)

    下载

    Client

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.IO;
    using System.Windows.Forms;
    
    
    namespace SocketClient
    {
        class Program
        {
            [STAThread]
            static void Main(string[] args)
            {
                SocketClient();
            }
            public static string serverIp = "127.0.0.1";//设置服务端IP
            public static int serverPort = 8888;//服务端端口
            public static Socket socketClient;//定义socket
            public static Thread threadClient;//定义线程
            public static byte[] result = new byte[1024];//定义缓存
            public static void SocketClient()
            {
                socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个socket的对象
                IPAddress ip = IPAddress.Parse(serverIp);//获取服务器IP地址
                IPEndPoint point = new IPEndPoint(ip, serverPort);//获取端口
                try
                {
                    socketClient.Connect(point);//链接服务器IP与端口
                    Console.WriteLine("连接服务器中.....");
    
                }
                catch (Exception)
                {
                    Console.WriteLine("与服务器链接失败!!!");
                    return;
                }
                Console.WriteLine("与服务器链接成功!!!");
                try
                {
                    Thread.Sleep(1000);    //等待1秒钟  
                    //通过 socketClient 向服务器发送数据
                    string sendMessage = "已成功接到SocketClient发送的消息";//发送到服务端的内容
                    byte[] send = Encoding.UTF8.GetBytes(sendMessage);//Encoding.UTF8.GetBytes()将要发送的字符串转换成UTF8字节数组
                    byte[] SendMsg = new byte[send.Length + 1];//定义新的字节数组
                    SendMsg[0] = 0;//将数组第一位设置为0,来表示发送的是消息数据  
                    Buffer.BlockCopy(send, 0, SendMsg, 1, send.Length);//偏移复制字节数组
                    socketClient.Send(SendMsg);  //将接受成功的消息返回给SocketServer服务器 
                    Console.WriteLine("发送完毕:{0}", sendMessage);
    
                }                                                                                                                     
                catch
                {
                    socketClient.Shutdown(SocketShutdown.Both);//禁止Socket上的发送和接受
                    socketClient.Close();//关闭Socket并释放资源
                }
                //打开文件
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Title = "选择要传的文件";
                ofd.InitialDirectory = @"E:IVSDown";
                //ofd.Filter = "文本文件|*.txt|图片文件|*.jpg|视频文件|*.avi|所有文件|*.*";
                ofd.ShowDialog();
                //得到选择文件的路径
                string filePath = ofd.FileName;//获取文件的完整路径
                Console.WriteLine("发送的文件路径为:"+filePath);
                using (FileStream fsRead = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Read))
                {
                    //1. 第一步:发送一个文件,表示文件名和长度,让客户端知道后续要接收几个包来重新组织成一个文件
                    string fileName = Path.GetFileName(filePath);
                    Console.WriteLine("发送的文件名是:" + fileName);
                    long fileLength = fsRead.Length;//文件长度
                    Console.WriteLine("发送的文件长度为:"+fileLength);
                    string totalMsg = string.Format("{0}-{1}", fileName, fileLength);
                    byte[] buffer = Encoding.UTF8.GetBytes(totalMsg); 
                    byte[] newBuffer = new byte[buffer.Length + 1];
                    newBuffer[0] = 2;
                    Buffer.BlockCopy(buffer, 0, newBuffer, 1, buffer.Length);
                    socketClient.Send(newBuffer);//发送文件前,将文件名和长度发过去
                    //2第二步:每次发送一个1MB的包,如果文件较大,则会拆分为多个包
                    byte[] Filebuffer = new byte[1024 * 1024 * 5];//定义1MB的缓存空间
                    int readLength = 0;  //定义读取的长度
                    bool firstRead = true;
                    long sentFileLength = 0;//定义发送的长度
                    while ((readLength = fsRead.Read(buffer, 0, buffer.Length)) > 0 && sentFileLength < fileLength)
                    {
                        sentFileLength += readLength;
                        //第一次发送的字节流上加个前缀1
                        if (firstRead)
                        {
                            byte[] firstBuffer = new byte[readLength + 1];
                            firstBuffer[0] = 1;//标记1,代表为文件
                            Buffer.BlockCopy(buffer, 0, firstBuffer, 1, readLength);
                            socketClient.Send(firstBuffer, 0, readLength + 1, SocketFlags.None);
                            Console.WriteLine("第一次读取数据成功,在前面添加一个标记");
                            firstRead = false;
                            continue;
                        }
                        socketClient.Send(buffer, 0, readLength, SocketFlags.None);
                        Console.WriteLine("{0}: 已发送数据:{1}/{2}", socketClient.RemoteEndPoint, sentFileLength, fileLength);
                    }
                    fsRead.Close();
                    Console.WriteLine("发送完成");
                }
                Console.ReadLine();
            }
        }
    
    }

    Server

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Net;
    using System.Net.Sockets;
    using System.Threading;
    using System.IO;
    using System.Windows.Forms;
    
    namespace SocketServer
    {
        class Program
        {
            [STAThread]
            static void Main(string[] args)
            {
                SocketServer();
            }
            public static string serverIp = "127.0.0.1";//设置服务端IP
            public static int serverPort = 8888;//服务端端口
            public static Socket socketServer;//定义socket
            public static Thread threadWatch;//定义线程
            public static byte[] result = new byte[1024 * 1024 * 2];//定义缓存
            //public static string fileName;//获取文件名
            public static string filePath = "";//存储保存文件的路径
            public static void SocketServer()
            {
                socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//创建一个socket的对象
                IPAddress ip = IPAddress.Parse(serverIp);//获取服务器IP地址
                IPEndPoint point = new IPEndPoint(ip, serverPort);//获取端口
                try
                {
                    socketServer.Bind(point);//绑定IP地址及端口
                }
                catch (Exception ex)
                {
                    Console.WriteLine("绑定IP时出现异常:" + ex.Message);
                    return;
                }
                socketServer.Listen(100);//开启监听并设定最多10个排队连接请求
                threadWatch = new Thread(WatchConnect);//创建一个监听进程
                threadWatch.IsBackground = true;//后台启动
                threadWatch.Start();//运行
                Console.WriteLine("服务器{0}监听启动成功!", socketServer.LocalEndPoint.ToString());
                Console.ReadLine();
            }
            public static void WatchConnect()
            {
                while (true)
                {
                    Socket watchConnect = socketServer.Accept();//接收连接并返回一个新的Socket
                    watchConnect.Send(Encoding.UTF8.GetBytes("服务器连接成功"));//在客户端显示"服务器连接成功"提示
                    Thread threadwhat = new Thread(ReceiveMsg);//创建一个接受信息的进程
                    threadwhat.IsBackground = true;//后台启动
                    threadwhat.Start(watchConnect);//有传入参数的线程
                }
            }
            public static DateTime GetTime()
            {
                DateTime now = new DateTime();
                now = DateTime.Now;
                return now;
            }
            public static void ReceiveMsg(object watchConnect)
            {
                Socket socketServer = watchConnect as Socket;
                long fileLength = 0;//文件长度
                string recStr = null;//文件名
                while (true)
                {
                    int firstRcv = 0;
                    byte[] buffer = new byte[1024 * 1024 * 5];
                    try
                    {
                        //获取接受数据的长度,存入内存缓冲区,返回一个字节数组的长度
                        if (socketServer != null) firstRcv = socketServer.Receive(buffer);
                        if (firstRcv > 0)//大于0,说明有东西传过来
                        {
                            if (buffer[0] == 0)//0对应文字信息
                            {
                                string recMsg = Encoding.UTF8.GetString(buffer, 1, firstRcv - 1);
                                Console.WriteLine("客户端接收到信息:" + socketServer.LocalEndPoint.ToString() + "
    " + GetTime() + "
    " + recMsg + "
    ");
                            }
    
                            if (buffer[0] == 1)//1对应文件信息
                            {
                                SaveFileDialog sfDialog = new SaveFileDialog();//创建SaveFileDialog实例
                                string spath = @"E:存放";//制定存储路径
                                string savePath = Path.Combine(spath, recStr);//获取存储路径及文件名
                                int rec = 0;
                                long recFileLength = 0;
                                bool firstWrite = true;
                                using (FileStream fs = new FileStream(savePath, FileMode.Create, FileAccess.Write))
                                {
                                    while (recFileLength < fileLength)
                                    {
                                        if (firstWrite)
                                        {
                                            fs.Write(buffer, 1, firstRcv - 1);
                                            fs.Flush();
                                            recFileLength += firstRcv - 1;
                                            firstWrite = false;
                                        }
                                        else
                                        {
                                            rec = socketServer.Receive(buffer);
                                            fs.Write(buffer, 0, rec);
                                            fs.Flush();
                                            recFileLength += rec;
                                        }
                                        Console.WriteLine("{0}: 已接收数据:{1}/{2}", socketServer.RemoteEndPoint, recFileLength, fileLength);
                                    }
                                    fs.Close();
                                }
                                Console.WriteLine("保存成功!!!!");
                            }
                            if (buffer[0] == 2)//2对应文件名字和长度
                            {
                                string fileNameWithLength = Encoding.UTF8.GetString(buffer, 1, firstRcv - 1);
                                recStr = fileNameWithLength.Split('-').First();//获取文件名
                                Console.WriteLine("接收到的文件名为:" + recStr);
                                fileLength = Convert.ToInt64(fileNameWithLength.Split('-').Last());//获取文件长度
                                Console.WriteLine("接收到的文件长度为:" + fileLength);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("系统异常..." + ex.Message);
                        break;
                    }
                }
    
                //while (true)
                //{
                //    int num = -1;//初始化num
                //    string reveiceName;//定义字符串
                //    try
                //    {
                //        num = socketClient.Receive(result);//获取客户端信息
                //        reveiceName = Encoding.UTF8.GetString(result, 0, num);//把从0到num的字节变成String
                //    }
                //    catch (SocketException ex)
                //    {
                //        Console.WriteLine("异常:" + ex.Message + ", RemoteEndPoint: " + socketClient.RemoteEndPoint.ToString());
                //        break;
                //    }
                //    catch (Exception ex)
                //    {
                //        Console.WriteLine("异常:" + ex.Message);
                //        break;
                //    }
    
                //while (true)
                //{
    
                //try
                //{
                //    /// <summary>
                //    /// 存储大文件的大小
                //    /// </summary>
                //   long length = 0;
                //   long recive = 0; //接收的大文件总的字节数
                //    while (true)
                //    {
                //        byte[] buffer = new byte[1024 * 1024];
                //        int r = socketClient.Receive(buffer);
                //        Console.WriteLine("接受到的字符长度" + r);
                //        if (r == 0)
                //        {
                //            break;
                //        }
                //        Console.WriteLine("第二次的length长度为:" + length);
                //        if (length > 0)  //判断大文件是否已经保存完
                //        {
                //            //保存接收的文件
                //            using (FileStream fsWrite = new FileStream(filePath, FileMode.Append, FileAccess.Write))
                //            {
                //                Console.WriteLine("-----------------11111111111111111111111-----------------------------");
                //                fsWrite.Write(buffer, 0, r);
                //                length -= r; //减去每次保存的字节数
                //                Console.WriteLine("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive - length, recive);
                //                if (length <= 0)
                //                {
                //                    Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
                //                }
                //                continue;
                //            }
                //        }
                //        if (buffer[0] == 0) //如果接收的字节数组的第一个字节是0,说明接收的字符串信息
                //        {
                //            string strMsg = Encoding.UTF8.GetString(buffer, 1, r - 1);
                //            Console.WriteLine("*****************0000000000000000000000*********************");
                //            Console.WriteLine(socketClient.RemoteEndPoint.ToString() + ": " + strMsg);
                //        }
                //        else if (buffer[0] == 1) //如果接收的字节数组的第一个字节是1,说明接收的是文件
                //        {
                //            Console.WriteLine("++++++++++++++111111111111111111111+++++++++++++++++++");
                //            length = int.Parse(Encoding.UTF8.GetString(buffer, 1, r - 1));
                //            recive = length;
                //            Console.WriteLine("接收到的字节长度是多少呢:?" + length);
                //            SaveFileDialog sfd = new SaveFileDialog();
                //            sfd.Title = "保存文件";
                //            sfd.InitialDirectory = @"C:UsersAdministratorDesktop";
                //            //sfd.Filter = "文本文件|*.txt|图片文件|*.jpg|视频文件|*.avi|所有文件|*.*";
                //            //如果没有选择保存文件路径就一直打开保存框
                //            SaveFileDialog save = new SaveFileDialog();//创建SaveFileDialog实例
                //            string spath = @"C:UsersadminDesktop";//制定存储路径
                //            filePath = Path.Combine(spath, fileName);//获取存储路径及文件名
                //        }
                //    }
                //}
                //catch { }
    
                //}
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
                //try
                //{
                //    if (reveiceName[0] == 0)//判断数组第一个值,如果为0则说明传的是信息
                //    {
                //        fileName = Encoding.UTF8.GetString(result, 1, num - 1);//提取字节信息并转换成String
                //        Console.WriteLine("接收客户端的消息:{0}", fileName);
                //    }
                //    if (reveiceName[0] == 1)//判断数组第一个值,如果为1则说明传的是文件
                //    {
                //        SaveFileDialog save = new SaveFileDialog();//创建SaveFileDialog实例
                //        string spath = @"C:UsersadminDesktop";//制定存储路径
                //        string fullPath = Path.Combine(spath, fileName);//获取存储路径及文件名
                //        //FileStream filesave = new FileStream(fullPath, FileMode.Create, FileAccess.Write);//创建文件流,用来写入数据
                //        //filesave.Write(result, 1, num - 1);//将数据写入到文件中
                //        //filesave.Close();
                //        //Console.WriteLine("保存成功!!!");
                //        //**************************************************************************************************
                //        while (true)
                //        {
                //            byte[] buffer = new byte[1024 * 1024];
                //            int r = socketClient.Receive(buffer);
                //            Console.WriteLine("从客户端接收到的字节数:"+r);
                //            //string leng = Encoding.UTF8.GetString(buffer, 1, r - 1);
                //            int recive = r - 1;
                //            //Console.WriteLine(leng);
                //            //long recive = int.Parse(leng);
                //            //long recive = Convert.ToInt64(Encoding.UTF8.GetString(buffer, 1, r - 1));
                //            Console.WriteLine("总接受字节数:" + recive);
                //            long length = recive;
                //            Console.WriteLine("*******************************************");
                //            if (length > 0)
                //            {
                //                using (FileStream fsWrite = new FileStream(fullPath, FileMode.Append, FileAccess.Write))
                //                {
                //                    Console.WriteLine("---------*************--------------");
                //                    fsWrite.Write(buffer,1, r-1);
                //                    length -= r; //减去每次保存的字节数
                //                    Console.WriteLine("剩余接受字节数:"+length);
                //                    Console.WriteLine(string.Format("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive - length, recive));
                //                    if (length <= 0)
                //                    {
                //                        Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
                //                    }
                //                }
                //            }
                //        }
    
    
                //        //long recive = 0; //接收的大文件总的字节数
                //        //while (true)
                //        //{
                //        //    //byte[] buffer = new byte[1024 * 1024];
                //        //    //int r = socketClient.Receive(buffer);
    
                //        //    if (num == 0)
                //        //    {
                //        //        break;
                //        //    }
                //        //    if (length > 0)  //判断大文件是否已经保存完
                //        //    {
                //        //        //保存接收的文件
                //        //        using (FileStream fsWrite = new FileStream(fullPath, FileMode.Append, FileAccess.Write))
                //        //        {
                //        //            fsWrite.Write(result, 1, num-1);
                //        //            length -= num; //减去每次保存的字节数
                //        //            Console.WriteLine(string.Format("{0}: 已接收:{1}/{2}", socketClient.RemoteEndPoint, recive-length, recive));
                //        //            if (length <= 0)
                //        //            {
                //        //               Console.WriteLine(socketClient.RemoteEndPoint + ": 接收文件成功");
                //        //            }
                //        //            continue;
                //        //        }                        
                //        //    }
                //    }
                //}
                //catch (Exception ex)
                //{
    
                //    Console.WriteLine(ex.Message);
                //}
    
                //}
    
            }
        }
    }
  • 相关阅读:
    Mysql数据库基本操作
    Entity Framework 实践系列 —— 搞好关系 单相思(单向一对一,onetoone)
    ADO.NET最佳实践
    C++试题1
    SQL操作(初级、中级、高级)
    存储过程入门与提高
    数据库学习笔记
    触发器设计技巧与实例
    UML在关系型数据库设计中的应用
    数据库设计的一些构想
  • 原文地址:https://www.cnblogs.com/macT/p/11661735.html
Copyright © 2011-2022 走看看