苏飞论坛

标题: c#Socket文件的传输 [打印本页]

作者: 站长苏飞    时间: 2012-11-14 13:19
标题: c#Socket文件的传输
Socket文件传输一直是一个问题,下面也只是提供一个简单的方法,实际使用过程中还希望大家多提提建议。
好了大家直接看代码吧。
服务器端:
[code=csharp]    namespace Server  
    {  
        public delegate void ReceiveCompletedEventHandler(string bagSize, string Address, string SendedCount, string SendFileName, string bagCount, string bagLast);  
        public partial class Form1 : Form  
        {  
            public Form1()  
            {  
                InitializeComponent();  
                this.dataGridView1.AllowUserToAddRows = false;  
                this.ReceiveCompleted += new ReceiveCompletedEventHandler(Form1_ReceiveCompleted);  
            }  
      
            void Form1_ReceiveCompleted(string bagSize, string Address, string SendedCount, string SendFileName, string bagCount, string bagLast)  
            {  
                if (this.dataGridView1.InvokeRequired)  
                {  
                    this.dataGridView1.Invoke(new ReceiveCompletedEventHandler(Form1_ReceiveCompleted), bagSize, Address, SendedCount, SendFileName, bagCount, bagLast);  
                }  
                else  
                {  
                    this.dataGridView1.Rows.Add(bagSize, Address, SendedCount, SendFileName, bagCount, bagLast);  
                }  
            }  
            Thread thread;  
            private void Form1_Load(object sender, EventArgs e)  
            {  
                //开启接受线程  
                thread = new Thread(new ThreadStart(StartReceive));  
                thread.Start();  
            }  
      
            private event ReceiveCompletedEventHandler ReceiveCompleted;  
      
      
            private void Completed(string bagSize, string Address, string SendedCount, string SendFileName, string bagCount, string bagLast)  
            {  
                if (ReceiveCompleted != null)  
                {  
                    ReceiveCompleted(bagSize, Address, SendedCount, SendFileName, bagCount, bagLast);  
                }  
            }  
            Socket client;  
            Socket server;  
     
            #region 功能函数  
            /// <summary>  
            /// 服务器端接收线程方法  
            /// </summary>  
            private void StartReceive()  
            {  
                //创建一个网络端点  
                IPEndPoint ipep = new IPEndPoint(IPAddress.Any, int.Parse("2010"));  
      
                //MessageBox.Show(IPAddress.Any);  
      
                //创建一个套接字  
                server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
      
                //绑定套接字到端口  
                server.Bind(ipep);  
      
                //开始侦听(并堵塞该线程)  
                server.Listen(10);  
                while (true)  
                {  
                    //确认连接  
                    client = server.Accept();  
                    //获得客户端节点对象  
                    Thread ThreadClient = new Thread(new ThreadStart(ClientMethod));  
                    ThreadClient.Start();  
                }  
            }  
      
            private void ClientMethod()  
            {  
                IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;  
      
                //获得[文件名]  
                string SendFileName = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));  
                //MessageBox.Show("文件名" + SendFileName);  
      
                //获得[包的大小]  
                string bagSize = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));  
                //MessageBox.Show("包大小" + bagSize);  
      
                //获得[包的总数量]  
                int bagCount = int.Parse(System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client)));  
                //MessageBox.Show("包的总数量" + bagCount);  
      
                //获得[最后一个包的大小]  
                string bagLast = System.Text.Encoding.Unicode.GetString(TransferFiles.ReceiveVarData(client));  
                //MessageBox.Show("最后一个包的大小" + bagLast);  
      
                string filepath = null;  
                string fileName = SendFileName;  
                string fileNameExt = fileName.Substring(fileName.LastIndexOf(".") + 1);  
                if (fileNameExt == "svd")  
                {  
                    filepath = @"D:\FileSave\SVD\";  
                    if (!Directory.Exists(filepath))  
                        Directory.CreateDirectory(filepath).ToString();  
                }  
                else if (fileNameExt == "jpg")  
                {  
                    filepath = @"D:\FileSave\JPG\";  
                    if (!Directory.Exists(filepath))  
                        Directory.CreateDirectory(filepath).ToString();  
                }  
                else  
                {  
                    filepath = @"D:\FileSave\File\";  
                    if (!Directory.Exists(filepath))  
                        Directory.CreateDirectory(filepath).ToString();  
                }  
      
                //创建一个新文件  
                FileStream MyFileStream = new FileStream(filepath + SendFileName, FileMode.Create, FileAccess.Write);  
      
                //已发送包的个数  
                int SendedCount = 0;  
      
                while (true)  
                {  
                    byte[] data = TransferFiles.ReceiveVarData(client);  
                    if (data.Length == 0)  
                    {  
                        break;  
                    }  
                    else  
                    {  
                        SendedCount++;  
                        //将接收到的数据包写入到文件流对象  
                        MyFileStream.Write(data, 0, data.Length);  
                        //显示已发送包的个数  
                        //MessageBox.Show("已发送包个数"+SendedCount.ToString());  
                    }  
                }  
      
                //关闭文件流  
                MyFileStream.Close();  
                //关闭套接字  
                client.Close();  
                Completed(bagSize, clientep.Address.ToString(), SendedCount.ToString(), SendFileName, bagCount.ToString(), bagLast);  
            }  
            #endregion  
      
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)  
            {  
                try  
                {  
                    server.Close();  
                    Application.Exit();  
                }  
                catch (Exception)  
                {  
                     
                    throw;  
                }  
            }  
        }  
    }  [/code]
客户端:
[code=csharp]    public Form1()  
           {  
               InitializeComponent();  
               this.textBox4.Text = Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString();  
           }  
      
           //发送  
           private void button2_Click(object sender, EventArgs e)  
           {  
               if (textBox7.Text.Trim() == "")  
               {  
                   MessageBox.Show("接收端IP不能为空!");  
                   return;  
               }  
               progressBar1.Value = 0;  
               button2.Enabled = false;  
               Thread TempThread = new Thread(new ThreadStart(this.StartSend));  
               TempThread.Start();  
                 
           }  
      
      
           /// <summary>  
           /// 客户端文件传输子线程方法(上传方法)  
           /// </summary>  
           private void StartSend()  
           {  
               if (this.InvokeRequired)  
               {  
                   this.Invoke(new ThreadStart(StartSend));  
               }  
               else  
               {  
                   //创建一个文件对象  
                   FileInfo EzoneFile = new FileInfo(this.textBox1.Text);  
                   //打开文件流  
                   FileStream EzoneStream = EzoneFile.OpenRead();  
                   //包的大小  
                   int PacketSize = int.Parse(this.textBox6.Text);  
                   //包的数量  
                   int PacketCount = (int)(EzoneStream.Length / ((long)PacketSize));  
                   this.textBox8.Text = PacketCount.ToString();  
      
                   this.progressBar1.Maximum = PacketCount;  
                   //最后一个包的大小  
                   int LastDataPacket = (int)(EzoneStream.Length - ((long)(PacketSize * PacketCount)));  
                   this.textBox9.Text = LastDataPacket.ToString();  
      
                   ////创建一个网络端点  
                   //IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("192.168.1.136"), int.Parse(this.textBox5.Text));  
      
                   ////MessageBox.Show(IPAddress.Any);  
      
                   ////创建一个套接字  
                   //Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
      
                   //MessageBox.Show(server.ToString());  
                   //指向远程服务端节点  
                   IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(textBox7.Text.Trim()), int.Parse(this.textBox5.Text));  
                   //创建套接字  
                   Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);  
                   //连接到发送端  
                   client.Connect(ipep);  
                   ////绑定套接字到端口  
                   //client.Bind(ipep);  
      
                   //MessageBox.Show(ipep.ToString());  
      
                   ////开始侦听(并堵塞该线程)  
                   //server.Listen(10);  
                   //确认连接  
                   //Socket client = server.Accept();  
      
                   //MessageBox.Show(client.ToString());  
      
                   //获得客户端节点对象  
                   IPEndPoint clientep = (IPEndPoint)client.RemoteEndPoint;  
                   //获得客户端的IP地址  
                   //this.textBox7.Text=clientep.Address.ToString();  
                   //发送[文件名]到客户端  
                   CommonModule.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(EzoneFile.Name));  
                   //发送[包的大小]到客户端  
                   CommonModule.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(PacketSize.ToString()));  
                   //发送[包的总数量]到客户端  
                   CommonModule.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(PacketCount.ToString()));  
                   //发送[最后一个包的大小]到客户端  
                   CommonModule.SendVarData(client, System.Text.Encoding.Unicode.GetBytes(LastDataPacket.ToString()));  
      
                   //数据包  
                   byte[] data = new byte[PacketSize];  
                   //开始循环发送数据包  
                   for (int i = 0; i < PacketCount; i++)  
                   {  
                       //从文件流读取数据并填充数据包  
                       EzoneStream.Read(data, 0, data.Length);  
                       //发送数据包  
                       CommonModule.SendVarData(client, data);  
                       //显示发送数据包的个数  
                       this.textBox10.Text = ((int)(i + 1)).ToString();  
                       //进度条值的显示  
                       this.progressBar1.PerformStep();  
                   }  
      
                   //如果还有多余的数据包,则应该发送完毕!  
                   if (LastDataPacket != 0)  
                   {  
                       data = new byte[LastDataPacket];  
                       EzoneStream.Read(data, 0, data.Length);  
                       CommonModule.SendVarData(client, data);  
                       this.progressBar1.Value = this.progressBar1.Maximum;  
                   }  
      
                   //关闭套接字  
                   client.Close();  
                   //server.Close();  
                   //关闭文件流  
                   EzoneStream.Close();  
                   this.button2.Enabled = true;  
                   MessageBox.Show("文件传输完毕!");  
               }  
           }  
      
           //浏览文件  
           private void button1_Click(object sender, EventArgs e)  
           {  
               if (openFileDialog1.ShowDialog() == DialogResult.OK)  
               {  
                   FileInfo info = new FileInfo(openFileDialog1.FileName);  
                   textBox1.Text = info.FullName;  
                   textBox2.Text = info.Name;  
                   textBox3.Text = info.Length.ToString();  
               }  
           }  [/code]
公共类代码:
[code=csharp]    class CommonModule  
       {  
           public static int SendData(Socket s, byte[] data)  
           {  
               int total = 0;  
               int size = data.Length;  
               int dataleft = size;  
               int sent;  
      
               while (total < size)  
               {  
                   sent = s.Send(data, total, dataleft, SocketFlags.None);  
                   total += sent;  
                   dataleft -= sent;  
               }  
      
               return total;  
           }  
      
           public static byte[] ReceiveData(Socket s, int size)  
           {  
               int total = 0;  
               int dataleft = size;  
               byte[] data = new byte[size];  
               int recv;  
               while (total < size)  
               {  
                   recv = s.Receive(data, total, dataleft, SocketFlags.None);  
                   if (recv == 0)  
                   {  
                       data = null;  
                       break;  
                   }  
      
                   total += recv;  
                   dataleft -= recv;  
               }  
               return data;  
           }  
      
           public static int SendVarData(Socket s, byte[] data)  
           {  
               int total = 0;  
               int size = data.Length;  
               int dataleft = size;  
               int sent;  
               byte[] datasize = new byte[4];  
               datasize = BitConverter.GetBytes(size);  
               sent = s.Send(datasize);  
      
               while (total < size)  
               {  
                   sent = s.Send(data, total, dataleft, SocketFlags.None);  
                   total += sent;  
                   dataleft -= sent;  
               }  
      
               return total;  
           }  
      
           public static byte[] ReceiveVarData(Socket s)  
           {  
               int total = 0;  
               int recv;  
               byte[] datasize = new byte[4];  
               recv = s.Receive(datasize, 0, 4, SocketFlags.None);  
               int size = BitConverter.ToInt32(datasize, 0);  
               int dataleft = size;  
               byte[] data = new byte[size];  
               while (total < size)  
               {  
                   recv = s.Receive(data, total, dataleft, SocketFlags.None);  
                   if (recv == 0)  
                   {  
                       data = null;  
                       break;  
                   }  
                   total += recv;  
                   dataleft -= recv;  
               }  
               return data;  
           }  
       }  [/code]
参考资源:http://net-liu.iteye.com/blog/678005





欢迎光临 苏飞论坛 (http://www.sufeinet.com/) Powered by Discuz! X3.4