使用Socket实现网络传输

来源:互联网 发布:淘宝平价软妹衣服推荐 编辑:程序博客网 时间:2024/05/01 08:02

           类似的博文很多了,但是质量良莠不齐,有的可用性、可移植性比较差。这段代码我调试了两天,运行起来性能、稳定型不错。要求不高的中、小程序直接作为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;        }    }