zoukankan      html  css  js  c++  java
  • C# socket编程第四篇

          在第三篇里已经实现了文件的传输,但是在第三篇里,传输的文件是用一个包传过去的,如果文件大点的话,就无法实现了,今天我们来讲如何将大文件分包来处理。既然一个大文件不能一次传,那就要多次传了,既然是多次,那就要分包了。先把demo贴出,程序中都有注释。

    服务端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net.Sockets;
    using System.Net;
    using System.IO;
    namespace FileReceiveControl
    {
    public class FileOutPackets
    {
    public void GetFileOutPackets()
    {
    try
    {
    Console.WriteLine(
    "this is server");
    int Port = 8001;
    IPEndPoint ipep
    = new IPEndPoint(IPAddress.Any, Port);
    EndPoint ep
    = (EndPoint)ipep;
    Socket sc
    = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    sc.Bind(ep);

    IPEndPoint ipepClient
    = new IPEndPoint(IPAddress.Any, 0);
    EndPoint epClient
    = (EndPoint)ipepClient;

    int Rec;
    byte[] Bytes = new byte[1024];
    //=====获取文件名
    Rec = sc.ReceiveFrom(Bytes, ref epClient);
    string FileName = Encoding.ASCII.GetString(Bytes, 0, Rec);
    //=====向客服端 发送接收到的信号
    Bytes = Encoding.ASCII.GetBytes("1");
    sc.SendTo(Bytes, epClient);

    //======获取文件 bytes 大小
    Bytes = new byte[1024];
    Rec
    = sc.ReceiveFrom(Bytes, ref epClient);
    //=====向客服端 发送接收到的信号
    //Bytes = Encoding.ASCII.GetBytes("2");
    //sc.SendTo(Bytes, epClient);

    //=======获取fs bytes总的大小
    int FileByteLength = int.Parse(Encoding.ASCII.GetString(Bytes, 0, Rec));

    //=======获取总的包数量
    Bytes = new byte[1024];
    Rec
    = sc.ReceiveFrom(Bytes, ref epClient);
    //=======获取总的包数量
    int PacketNum = int.Parse(Encoding.ASCII.GetString(Bytes, 0, Rec));
    Console.WriteLine(
    "packetNum is " + PacketNum);
    //====获取最后一个包的大小
    Bytes = new byte[1024];
    Rec
    = sc.ReceiveFrom(Bytes, ref epClient);
    int FinalPacketSize = int.Parse(Encoding.ASCII.GetString(Bytes, 0, Rec));
    string TempPath = @"E:\" + FileName + ".temp";
    FileStream fs
    = new FileStream(TempPath, FileMode.OpenOrCreate, FileAccess.Write);
    //======循环 接收
    for (int i = 0; i < PacketNum; i++)
    {
    byte[] Data = new byte[8192];
    Rec
    = sc.ReceiveFrom(Data, ref epClient);
    fs.Write(Data,
    0, 8192);
    fs.Flush();
    Console.WriteLine(
    "this is " + (i + 1) + " packet");
    }
    if (FinalPacketSize != 0)
    {
    byte[] data = new byte[FinalPacketSize];
    Rec
    = sc.ReceiveFrom(data, ref epClient);
    fs.Write(data,
    0, FinalPacketSize);
    fs.Flush();
    }
    fs.Close();
    sc.Close();

    FileStream FsMove
    = new FileStream(TempPath, FileMode.Open, FileAccess.Read);

    string Path = TempPath.Remove(TempPath.Length - 5, 5);
    byte[] ByteFile = new byte[FsMove.Length];
    FsMove.Read(ByteFile,
    0, (int)FsMove.Length);
    File.WriteAllBytes(Path, ByteFile);
    FsMove.Close();
    File.Delete(TempPath);
    Console.WriteLine(
    "receive is over");
    //===========死循环 方便调试 避免直接退出
    while (true)
    {

    }
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.ToString());
    }
    }
    }
    }

    客户端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Net;
    using System.Net.Sockets;
    using System.IO;
    using System.Threading;
    namespace FileDistributeControl
    {
    public class FileOutPackets
    {
    public void GetFileOutPackets()
    {
    Console.WriteLine(
    "this is client");
    int Port=8001;
    string Ip="192.168.1.20";
    IPEndPoint ipep
    = new IPEndPoint(IPAddress.Parse(Ip), Port);
    EndPoint ep
    = (EndPoint)ipep;
    Socket sc
    = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

    string path = @"F:\1.jpg";
    FileInfo fino
    = new FileInfo(path);

    IPEndPoint ipepClient
    = new IPEndPoint(IPAddress.Any,0);
    EndPoint epClient
    = (EndPoint)ipepClient;

    int Rec,Rtn;
    byte[] Bytes=new byte[1024];
    //=========发送 文件名
    sc.SendTo(Encoding.ASCII.GetBytes(fino.Name),ep);

    Rec
    = sc.ReceiveFrom(Bytes,ref epClient);
    Rtn
    =int.Parse(Encoding.ASCII.GetString(Bytes,0,Rec));
    if (Rtn == 1)
    {
    Console.WriteLine(
    "this file name send successful");

    FileStream fs
    = new FileStream(path,FileMode.Open,FileAccess.Read);
    //=======取得最后一个数据包前的数据包总数 (int)将一个浮点数 转整型,只会四舍,不会五入
    //=======1k==1024B==1024*8b 1k等于2的10次方字节,一个字节等于8位
    int PacketNum = (int)(fs.Length /(long)8192);
    int EndPacket = (int)(fs.Length - PacketNum * 8192);
    //=======最后一个包有可能是0
    int TotalPacket;
    if (EndPacket == 0)
    {
    TotalPacket
    = PacketNum;
    }
    else
    {
    TotalPacket
    = PacketNum + 1;
    }

    //=======发送总 的数据包 etc
    sc.SendTo(Encoding.ASCII.GetBytes(fs.Length.ToString()), ep);
    sc.SendTo(Encoding.ASCII.GetBytes(PacketNum.ToString()), ep);
    sc.SendTo(Encoding.ASCII.GetBytes(EndPacket.ToString()),ep);
    //=======循环发送
    Console.WriteLine("packetNum is "+PacketNum);
    for (int i = 0; i < PacketNum; i++)
    {
    byte[] data = new byte[8192];
    fs.Read(data,
    0, 8192);
    sc.SendTo(data,ep);
    Console.WriteLine(
    "this is "+(i+1)+" packet");
    Thread.Sleep(
    300);
    }

    Console.WriteLine(
    "this for is over");
    //=======发送最后一个包
    if (EndPacket != 0)
    {
    byte[] finallData=new byte[EndPacket];
    fs.Read(finallData,
    0,EndPacket);
    sc.SendTo(finallData,ep);
    Console.WriteLine(
    "this is final packet");
    }

    Console.WriteLine(
    "send over");

    }
    else
    {
    //=======返回值不等于1 重新发送
    sc.SendTo(Encoding.ASCII.GetBytes(fino.Name),ep);
    }

    while (true)
    { }

    }
    }
    }
    这样就可以把一个大文件分成很多个包来进行发送了。这里需要注意的是,循环发送的时候需要休眠段时间,如果没有sleep这条语句,那么在服务端无法完整的收完每一个包。至于为什么一次性发完无法收取完,我现在也解释不了,在研究中...希望下一遍的时候可以解决这些问题..

  • 相关阅读:
    42. Trapping Rain Water
    223. Rectangle Area
    645. Set Mismatch
    541. Reverse String II
    675. Cut Off Trees for Golf Event
    安装 VsCode 插件安装以及配置
    向上取整 向下取整 四舍五入 产生100以内随机数
    JS 判断是否为数字 数字型特殊值
    移动端初始配置,兼容不同浏览器的渲染内核
    Flex移动布局中单行和双行布局的区别以及使用
  • 原文地址:https://www.cnblogs.com/_fyz/p/2042194.html
Copyright © 2011-2022 走看看