使用Socket实现网络传输

           类似的博文很多了,但是质量良莠不齐,有的可用性、可移植性比较差。这段代码我调试了两天,运行起来性能、稳定型不错。要求不高的中、小程序直接作为Dll类库引用没问题。

           发篇博文用来记录,也好分享给大家成果。此段代码仍有很多可以提高的地方,希望算是抛砖引玉。


需求:

       服务端(1):能够持续监听,并查收文件。

       客户端(N):能够连接服务器发送文件。

       使用效果测试:局域网内,4G的单个文件传输没问题。稳定性还是有保障的,而且内存消耗也比较稳定、可控。

       现有代码可以完善的问题一:服务端无法实现多个文件同时接收,请教各位高手给个思路?

       

public static class FileSender
    {
        private const int BufferSize = 1024;
        
        public static void Send(IPEndPoint ip, string fullPathFileName)
        {
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sock.Connect(ip);
            using (FileStream reader = new FileStream(fullPathFileName, FileMode.Open, FileAccess.Read, FileShare.None))
            {

                //发送文件长度
                long send = 0L, length = reader.Length;
                byte[] byteArrayLength = BitConverter.GetBytes(length);
                sock.Send(byteArrayLength);

                ///发送文件名
                string fileName = Path.GetFileName(fullPathFileName);
                byte[] bufferFileName = Encoding.Default.GetBytes(fileName);
                sock.Send(bufferFileName);

                //sock.Send(BitConverter.GetBytes());
                Console.WriteLine("Sending file:" + fileName + ";Size:" + length + "Byte;Please wait...");
                byte[] buffer = new byte[BufferSize];
                int read, sent;
                //断点发送 在这里判断设置reader.Position即可
                while ((read = reader.Read(buffer, 0, BufferSize)) != 0)
                {
                    sent = 0;
                    while ((sent += sock.Send(buffer, sent, read, SocketFlags.None)) < read)
                    {
                        send += (long)sent;
                        //Console.WriteLine("Sent " + send + "/" + length + ".");//进度
                    }
                }
                Console.WriteLine("Send finish.");
            }
        }

        public static bool ReceiverBusying = false;
        public static void Receive(int port, string path)
        {
            IPEndPoint ip = new IPEndPoint(IPAddress.Any, port);
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            sock.Bind(ip);
            sock.Listen(100);
            
            while (true)
            {
                Socket client = sock.Accept();
                ReceiverBusying = true;
                byte[] buffer = new byte[BufferSize];
                client.Receive(buffer);
                long receive = 0L, length = BitConverter.ToInt64(buffer,0);


                buffer = new byte[BufferSize];
                int receivedNum=client.Receive(buffer);
                string fileName = Encoding.Default.GetString(buffer, 0, receivedNum);

                Console.WriteLine("Receiving file:" + fileName + ";Size:" + length + "Byte; Please wait...");
                
                string targetPathFileName;
                try
                {
                    ///完整文件名
                    targetPathFileName = Path.Combine(path, fileName);
                }
                catch//用当前时间.xml
                {
                    targetPathFileName = Path.Combine(path, DateTime.Now.ToString("yyyyMMddHHmmss") + ".xml");
                }
                
                using (FileStream writer = new FileStream(targetPathFileName, FileMode.Create, FileAccess.Write, FileShare.None))
                {
                    int received;
                    //断点接受 在这里判断设置writer.Position即可
                    while (receive < length)
                    {
                        received = client.Receive(buffer);
                        writer.Write(buffer, 0, received);
                        writer.Flush();
                        receive += (long)received;
                        //Console.WriteLine("Received " + receive + "/" + length + ".");//进度
                    }
                }
                ReceiverBusying = false;
                Console.WriteLine("Receive finish.");
            }
        }

        /// <summary>
        /// 地址为默认路径
        /// </summary>
        /// <param name="ip"></param>
        public static void Receive(int port)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;
            Receive(port, path);
        }


        /// 比较两个字节数组是否相等
        /// </summary>
        /// <param name="b1">byte数组1</param>
        /// <param name="b2">byte数组2</param>
        /// <returns>是否相等</returns>
        public static bool PasswordEquals(byte[] b1, byte[] b2)
        {
            if (b1 == null || b2 == null) return false;
            if (b1.Length != b2.Length) return false;
            for (int i = 0; i < b1.Length; i++)
                if (b1[i] != b2[i])
                    return false;
            return true;
        }

    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值