C#.网络编程 Socket基础(三) 基于WinForm系统Socket TCP协议 实现端到端(服务器与客户端).txt.word.png等不同类型文件传输

一、简介:

前面的两篇介绍了字符串传输、图片传输:

Socket基础(一)字符串传输https://blog.csdn.net/xpj8888/article/details/83383355

Socket基础(二)图片传输https://blog.csdn.net/xpj8888/article/details/83443853

其实,本文针对Socket基础(二)进一步完成,以便可以进行多种文件传输。

二、基于不同的流(文件流、内存流、网络等)读写。

流知识,参考:

https://www.cnblogs.com/zxx193/p/3580564.html

https://blog.csdn.net/e295166319/article/details/52702461

微软官网https://docs.microsoft.com/zh-cn/dotnet/api/system.io.memorystream?view=netframework-4.7.2

1、图片传输

扫描二维码关注公众号,回复: 3763444 查看本文章

方法一:(在客户端用文件流发送(即将图片写到文件流去,以便发送),在服务端用内存流来接收(即从内存流读取图片出来))

详细见https://blog.csdn.net/xpj8888/article/details/83443853

方法二:(在客户端用文件流发送(即将图片写到文件流去,以便发送),在服务端也用文件流来接收(即从文件流读取图片出来))

客户端代码不变,请参考:https://blog.csdn.net/xpj8888/article/details/83443853

服务端代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SocketServer_SendImage
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //Form1_Load表示默认的加载,相当于初始化。
        private void Form1_Load(object sender, EventArgs e)
        {
            lab_pro.Text = "接收:0/100";
            //button1.Text = "BBBBB";
        }
        /// <summary>
        /// 开启服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Text = "监听中...";
            button1.Enabled = false;
            Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse("1.1.1.2"), 8888);

            //设置接收数据缓冲区的大小
            byte[] b = new byte[4096];
            receiveSocket.Bind(hostIpEndPoint);
            //监听
            receiveSocket.Listen(2);
            //接受客户端连接
            Socket hostSocket = receiveSocket.Accept();
            //内存流fs的初始容量大小为0,随着数据增长而扩展。
            //MemoryStream fs = new MemoryStream();
            string Path = "C:\\Users\\lanmage2\\Desktop\\AA";
            FileStream fs = new FileStream(Path + "\\新图片.png", FileMode.Create, FileAccess.Write);
            int length = 0;
            //每接受一次,只能读取小于等于缓冲区的大小4096个字节
            while ((length = hostSocket.Receive(b)) > 0)
            {
                //将接受到的数据b,按长度length放到内存流中。
                fs.Write(b, 0, length);

                if (progressBar1.Value < 100)
                {
                    //进度条的默认值为0
                    progressBar1.Value++;
                    lab_pro.Text = "接收:" + progressBar1.Value + "/100";
                }
            }
            progressBar1.Value = 100;
            lab_pro.Text = "接收:" + progressBar1.Value + "/100";
            fs.Flush();
            /*Bitmap类,可以将*/
            //Bitmap Img = new Bitmap(fs);
            //Img.Save(@"reveive.jpg", ImageFormat.Png);
            //关闭写文件流
            fs.Close();
            //关闭接收数据的Socket
            hostSocket.Shutdown(SocketShutdown.Receive);
            hostSocket.Close();
            //关闭发送连接
            receiveSocket.Close();
        }
    }
}

方法三

https://blog.csdn.net/z5976749/article/details/40743487

2、传输文档(比如.txt文档或其他)

方法一:

客户端代码不变,请参考:https://blog.csdn.net/xpj8888/article/details/83443853

服务端大部分代码参考 1、图片传输  方法二   的代码,但是其改动了截图部分

方法2:

在客户端用文件流发送(即将图片写到文件流去,以便发送),在服务端用内存流来缓存,并用文件流来输出,这种方法是最理想的,既可以传图片,可以传其他任意文件:

客户端代码不变,请参考:https://blog.csdn.net/xpj8888/article/details/83443853

服务器端:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SocketServer_SendImage
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //Form1_Load表示默认的加载,相当于初始化。
        private void Form1_Load(object sender, EventArgs e)
        {
            lab_pro.Text = "接收:0/100";
            //button1.Text = "BBBBB";
        }
        /// <summary>
        /// 开启服务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            button1.Text = "监听中...";
            button1.Enabled = false;
            Socket receiveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint hostIpEndPoint = new IPEndPoint(IPAddress.Parse("1.1.1.2"), 8888);

            //设置接收数据缓冲区的大小
            byte[] b = new byte[4096];
            receiveSocket.Bind(hostIpEndPoint);
            //监听
            receiveSocket.Listen(2);
            //接受客户端连接
            Socket hostSocket = receiveSocket.Accept();
            //内存流fs的初始容量大小为0,随着数据增长而扩展。
            MemoryStream fs = new MemoryStream();
            //string Path = "C:\\Users\\lanmage2\\Desktop\\AA";
            //FileStream fs = new FileStream(Path, FileMode.Open);
            int length = 0;
            //每接受一次,只能读取小于等于缓冲区的大小4096个字节
            while ((length = hostSocket.Receive(b)) > 0)
            {
                //将接受到的数据b,按长度length放到内存流中。
                fs.Write(b, 0, length);

                if (progressBar1.Value < 100)
                {
                    //进度条的默认值为0
                    progressBar1.Value++;
                    lab_pro.Text = "接收:" + progressBar1.Value + "/100";
                }
            }
            progressBar1.Value = 100;
            lab_pro.Text = "接收:" + progressBar1.Value + "/100";
            fs.Flush();
 
            fs.Seek(0, SeekOrigin.Begin);
            byte[] byteArray = new byte[fs.Length];
            int count = 0;
            while (count < fs.Length)
            {
                byteArray[count] = Convert.ToByte(fs.ReadByte());
                count++;
            }
            string Path = "C:\\Users\\lanmage2\\Desktop\\AA";
            //FileStream filestream = new FileStream(Path + "\\文件1.txt", FileMode.OpenOrCreate);
            FileStream filestream  = File.Create(Path);
            //filestream.Write(byteArray, 0, byteArray.Length);//不能用
            //System.IO.File.WriteAllBytes(Path, byteArray);//能用
         
            /*Bitmap类,可以将*/
            //Bitmap Img = new Bitmap(fs);
            //Img.Save(@"reveive.jpg", ImageFormat.Png);
            //关闭写文件流
            fs.Close();
            //关闭接收数据的Socket
            hostSocket.Shutdown(SocketShutdown.Receive);
            hostSocket.Close();
            //关闭发送连接
            receiveSocket.Close();
        }
    }
}

三、总结

本文随意可以传输不同类型的文件,但是没办法动态识别不同的文件类型,不够灵活。在我下一篇文章,将根据用户端发送的信息,将对不同的文件类型进行动态的识别。

猜你喜欢

转载自blog.csdn.net/xpj8888/article/details/83446667