【黑马程序员】Socket文件传输

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------


我们利用Socket网络编程不仅可以传送文字,也可以传送文件。不论是文字还是文件,我们都需要先把它们转换为字节流(byte[]类型)才能传输。当接收的那一方的Recive()方法监听到有数据传送过来之后,就会把它从字节流转换回文字或文件。那么程序如何在接收到字节流的时候,判断它是文字还是文件呢?这就要求我们给这个字节流添加一个特殊标识,比如说,如果标识是0,它接收到的是文字,如果标识是1,那么它接收到的是文件。这个标识应该在发送这段字节流之前就赋予byte类型的数组。在发送一方,当我们把某一个要发送的文件转换为字节流的时候,可以把第一个位置(索引为0)空出来,然后把这个位置的值赋予0(表示文字)或1(表示文件)。具体代码如下所示:

/// <summary>
        /// 浏览按钮点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBrowser_Click(object sender, EventArgs e)
        {
            //使用打开文件控件找到要发送的文件,并获取它的路径
            OpenFileDialog ofd = new OpenFileDialog();
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtFilePath.Text = ofd.FileName;    //显示路径
            }
        }

        /// <summary>
        /// 发送文件按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendFile_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtFilePath.Text))   //非空验证
            {
                MessageBox.Show("请选择发送的文件路径");
                return;
            }
            //创建一个字节数组,用于保存读取文件的数据流
            byte[] arrFile = new byte[1024 * 1024 * 2];
            //创建文件流,传入文件路径
            using (FileStream fs = new FileStream(txtFilePath.Text.Trim(), FileMode.Open))
            {
                arrFile[0] = 1;   //把字节数组第一个位置的值赋予1,表示传送的是文件
                //使用文件流的Read()方法把要发送的文件转换为字节赋予arrFile数组,
                //由于索引为0的位置已被赋值,所以真正存储文件字节的起始位置为1
                fs.Read(arrFile, 1, arrFile.Length - 1);
                //利用当前已经建立连接的Socket把要传输的字节发送出去
                socketClient.Send(arrFile);
            }
        }
在接收方收到数据(byte[])后,会先判断是文字还是文件,即判断获得的byte类型的数组的第一个位置的值。具体代码如下:
/// <summary>
        /// 发送消息按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSendMsg_Click(object sender, EventArgs e)
        {
            //把发送的消息转换为字节数组
            byte[] arrSendMsg = Encoding.UTF8.GetBytes(txtMessage.Text.Trim());
            //按照选定的IP端口,把消息发送到该客户端上
            connSockets[lbUniqueSign.SelectedItem.ToString()].Send(arrSendMsg);
            //显示消息
            ShowMsg(endpoint.ToString() + "发送消息:");
            ShowMsg("\t"+txtMessage.Text.Trim());
        }        

        /// <summary>
        /// 循环接收客户端发送过来的数据
        /// </summary>
        /// <param name="socketParam">当前与客户端通信的Socket</param>
        private void ReciveMessage(object socketParam)
        {
            //把参数由object类型转换为Socket类型
            Socket socketClient = socketParam as Socket;
            while (true)
            {
                //声明一个2M空间的字节数组
                byte[] arrRecMsg = new byte[1024 * 1024 * 2];
                //把接收到的字节存入字节数组中,并获取接收到的字节数
                int length = socketClient.Receive(arrRecMsg);
                //先取出字节数组中的值进行判断
                if (arrRecMsg[0] == 0)   //当前数据是文字
                {
                    //按照接收到的实际字节数获取发送过来的消息
                    ShowMsg(socketClient.RemoteEndPoint.ToString() + ":");
                    ShowMsg("\t" + Encoding.UTF8.GetString(arrRecMsg, 1, length-1));
                }
                else    //当前数据是文件 
                {
                    SaveFileDialog sfd = new SaveFileDialog();  //把文件另存为...
                    //DialogResult dr = sfd.ShowDialog();
                    if (sfd.ShowDialog() == DialogResult.OK)
                    {
                        string savePath = sfd.FileName;
                        using (FileStream fs = new FileStream(savePath,FileMode.Create))
                        {
                            fs.Write(arrRecMsg, 1, length - 1);  //保存传送过来的文件
                            ShowMsg("文件保存成功!" + savePath);
                        }
                    }
                }
            }
        }



---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值