Socket发送或接收文件

it2022-05-05  71

最近学习了一下Socket ,下面是实现像《飞鸽》类似的功能,这里只提供了简单的使用规则和一些做时遇到地饿问题,

算是备忘吧!! --------------------------------------------------- ----------使用UDP 发送数据报,到指定的网段---------         using System.Net;         using System.Net.Sockets;         using System.Windows.Forms;         using System.IO;

 /// <summary>         /// 启动所有线程         /// </summary>         private void StartThread()         {             //发送用户在线信息             Thread send = new Thread(new ThreadStart(this.SendUserInfo));             send.IsBackground = true;             send.Start();             //接收用户在线信息             Thread lsn = new Thread(new ThreadStart(this.StartListening));             lsn.IsBackground = true;             lsn.Start();                     //侦听消息和文件的传输端口             Thread sendMsg = new Thread(new ThreadStart(this.m_sendMSG.ListeningMSG));             sendMsg.IsBackground = true;             sendMsg.SetApartmentState(ApartmentState.STA);             sendMsg.Start();

        }

        /// <summary>         /// 发送UDP 数据报到指定网段内各终端机的 4095 端口         /// (发送在线用户信息)         /// </summary>         public void SendUserInfo()         {             UdpClient udpClient = new UdpClient();             IPEndPoint ep = new IPEndPoint(IPAddress.Parse("192.168.1.255"), 4095);

            string str = "user:" + System.Net.Dns.GetHostName()                 + ":" + System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList[0];

            byte[] dgram = System.Text.Encoding.Default.GetBytes(str);

            while (true)             {                 udpClient.Send(dgram, dgram.Length, ep);                   System.Threading.Thread.Sleep(2000); //使调用该方法的线程休眠2000毫秒             }         }

        /// <summary>         /// 接收 4095 端口所有数据包         /// (监听线用户发送的在线确认信息)         /// </summary>         public void StartListening()         {             UdpClient udpClient = new UdpClient(4095);//udp 通讯的端口号             IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);

            while (true)             {                 byte[] dgram = udpClient.Receive(ref ep);                 string str = System.Text.Encoding.Default.GetString(dgram);                 string[] arr = str.Split(':');                 if (arr == null || arr.Length < 3)                     continue;

                if (arr[0] != "user")                     continue;

                string houtName = arr[1];                 string ip = arr[2];                                 if (!hs.Contains(ip))                 {                     hs.Add(ip, houtName);                 }                                   ···  ···                }         }     }

------------------------------------------------------- -------------------通过 TCP 发送消息-------------------

1.通过指定的寻址方案,以字符流方式和Tcp通信,初始化套接字   socketSent = new Socket(AddressFamily.InterNetwork,                                    SocketType.Stream,                                    ProtocolType.Tcp); 2. 设置服务器IP地址和端口    ipSent = new IPEndPoint(IPAddress.Parse(ip), 8001);

3. 与服务器进行连接    socketSent.Connect(ipSent);

4. 将要发送的消息转化为字节流,然后发送    socketSent.Send(Encoding.Default.GetBytes(msg)); ----------------------------------------------------          通过 TCP 发送文件(最基本的设置)       首先要设置端口的监听,之后再发送数据包

1.命名空间: using System.Net; using System.Net.Sockets; using System.Windows.Forms; using System.IO;

2.监听端口设置     //初始化接受套接字:寻址方案,以字符流方式和Tcp通信   Socket socketMsg = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //获取本机IP地址   IPAddress hostIP=Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];   //   PEndPoint hostPoint=new IPEndPoint("本机IP地址",8000);   //设置服务器IP地址和端口   socketMsg.Bind(hostPoint);   //建立监听   socketMsg.Listen(1024);     while (true)   {       Socket newSocket = socketMsg.Accept();       //缓冲区       byte[] buffer = new byte[1024];        //接受数据流到缓冲区,len为接受到的字节数       int len = newSocket.Receive(buffer);       //创建写文件流       FileStream writer = new FileStream("c://test1.txt", FileMode.OpenOrCreate, FileAccess.Write);

      byte[] buffer = new byte[1024];       len  = newSocket.Receive(buffer)       string msg=Encoding.Default.GetString(buffer, 0, len );

      if(msg!="开始传送的标志符")   continue;          while ((len  = newSocket.Receive(buffer)) != 0)       {          msg = Encoding.Default.GetString(buffer, 0, len );

         if (msg == "结束传送的标志符")              break;    

         writer.Write(buffer, 0, len );       }          writer.Close();   }

3.送文件   //初始化文件读写流   FileStream readSream = new FileStream("c://test2.txt", FileMode.Open, FileAccess.Read);   //初始化接受套接字:寻址方案,以字符流方式和Tcp通信   Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);   //   IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("IP地址"), 8000);   //建立连接   socket.Connect(endPoint);

  //1.发送:文件发送开始标记和文件名   socket.Send(Encoding.Default.GetBytes("开始传送的标志符"));

  //2.发送文件   byte[] buffer = new byte[1024];   int n = 0;   while ((n = readSream.Read(buffer, 0, 1024)) != 0)   {        //调试时使用        //string str = Encoding.Default.GetString(buffer, 0, n);        //发送字节流        socket.Send(buffer,n,SocketFlags.None);        //socket.Send(buffer);   }

  //3.发送:文件发送结束符   socket.Send(Encoding.Default.GetBytes("结束传送的标志符"));

  socket.Close();   readSream.Close();  

---------------------------------------------------- 遇到的异常及解决方法: 1.在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式。请确保您的 Main 函数带有 STAThreadAttribute 标记。 只有将调试器附加到该进程才会引发此异常。   分析:因为使用线程,在线程中有调用了保存组件所以发生此异常   解决:将线程的模式设置为STA模式。         TreadName.SetApartmentState(ApartmentState.STA);

2.线程间操作无效: 从不是创建控件“lv”的线程访问它。   分析:因为在非本窗体的线程上,操作了本窗体的控件,所以引发了该异常。   解决:使用线程封送处理该问题,通过本窗体的 this.BeginInvoke() 方法,使其它线程可以操作窗体控件

        /// <summary>         /// 修改本窗体控件(封送处理所需的方法,该代理要于线程的方法的参数列表匹配)         /// </summary>         private delegate void InvokeInitIpList(ListeningAgos ags);

        /// <summary>         /// 线程调用的本窗体中的方法         /// </summary>         /// <param name="sa">包含所有在线用户信息</param>         void m_lsn_OnListening(ListeningAgos sa)         {             //在其它线程中通过安全的线程访问本窗体控件(其它线程访问本窗体控件,如不用该方法调用会发生异常)             //事件封送处理             this.BeginInvoke(new InvokeInitIpList(InitIpList),new object[]{sa});         }

 

 

 

 

 

 

转载于:https://www.cnblogs.com/xxj-jing/archive/2008/11/28/2890120.html

相关资源:各显卡算力对照表!

最新回复(0)