UDP打洞程序包的源码

C#实现UDP打洞

转自:http://hi.baidu.com/sdfiyon/blog/item/63a6e039155e02f23a87ceb1.html

下面是UDP打洞程序包的源码:
//WellKnown公用库
using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Net ;
using System.Net .Sockets ;
using System.Collections ;

namespace P2PWellKnown
{
/// <summary>
       /// UDP用户登录事件委托
/// </summary>
/// <param name="sender">事件源对象</param>
/// <param name="e">事件实体</param>
public delegate void UdpUserLogInDelegate(object sender,UDPSockEventArgs e);

       /// <summary>
       /// 一般UDP消息事件委托
       /// </summary>
       /// <param name="sender">事件源对象</param>
       /// <param name="e">事件实体</param>
       public delegate void UdpMessageDelegate(object sender,UDPSockEventArgs e);

       /// <summary>
       /// 初始化一个新连接的事件委托
       /// </summary>
       /// <param name="sender">事件源对象</param>
       /// <param name="e">事件实体</param>
       public delegate void UdpNewConnectDelegate(object sender,UDPSockEventArgs e);

/// <summary>
/// P2P共享数据类
/// </summary>
public class P2PConsts
{
     /// <summary>
     /// UDP服务器监听端口
     /// </summary>
     public const int UDP_SRV_PORT     = 2280;

     /// <summary>
     ///TCP服务器监听端口
     /// </summary>
     public const int TCP_SRV_PORT =2000;
}

   

/// <summary>
/// FormatterHelper 序列化,反序列化消息的帮助类
/// </summary>
public class FormatterHelper

{

     public static byte[] Serialize(object obj)

     {

      BinaryFormatter binaryF = new BinaryFormatter();

      MemoryStream ms = new MemoryStream(1024*10);

      binaryF.Serialize(ms, obj);

      ms.Seek(0, SeekOrigin.Begin);

      byte[] buffer = new byte[(int)ms.Length];

      ms.Read(buffer, 0, buffer.Length);

      ms.Close();

      return buffer;

     }

 

     public static object Deserialize(byte[] buffer)

     {

      BinaryFormatter binaryF = new BinaryFormatter();

      MemoryStream ms = new MemoryStream(buffer, 0, buffer.Length, false);

      object obj = binaryF.Deserialize(ms);

      ms.Close();

      return obj;

     }

}

 

/// <summary>
/// 用于承载UDPSock信息的事件类
/// </summary>
public class UDPSockEventArgs:EventArgs
{
     /// <summary>
     /// 要承载的消息
     /// </summary>
     private string m_strMsg;

     /// <summary>
     /// 用户信息
     /// </summary>
     private string m_strUserName;


           /// <summary>
           /// 触发该事件的公共终端
           /// </summary>
           private IPEndPoint m_EndPoint;


     /// <summary>
     /// 初始化UDPSock事件
     /// </summary>
     /// <param name="sMsg">用户发送的信息</param>
     public UDPSockEventArgs(string sMsg):base()
     {
      this.m_strMsg =sMsg;
     }

     /// <summary>
     /// 远端用户名
     /// </summary>
     public string RemoteUserName
     {
      get
      {
       return m_strUserName;
      }
      set
      {
       m_strUserName=value;
      }
     }


           /// <summary>
           /// 一般套接字消息
           /// </summary>
           public string SockMessage
           {
               get
               {
                   return m_strMsg;
               }
               set
               {
                   m_strMsg = value;
               }
           }


           /// <summary>
           /// 公共远端节点
           /// </summary>
           public IPEndPoint RemoteEndPoint
           {
               get
               {
                   return m_EndPoint;
               }
               set
               {
                   m_EndPoint = value;
               }
           }
}
}

 

//UDPP2PSock.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;

using P2PWellKnown;

namespace UDPP2P
{
       /// <summary>
       /// UDPP2P套接字管理类
       /// </summary>
       public class UDPP2PSock
       {
           /// <summary>
           /// 用户登录事件
           /// </summary>
           public event UdpUserLogInDelegate OnUserLogInU;

           /// <summary>
           /// 一般UDP消息事件
           /// </summary>
           public event UdpMessageDelegate OnSockMessageU;

           /// <summary>
           /// 初始化一个新连接事件
           /// </summary>
           public event UdpNewConnectDelegate OnNewConnectU;

           /// <summary>
           /// UDP服务器
           /// </summary>
           private UdpClient m_udpServer;

           /// <summary>
           /// UDP客户端
           /// </summary>
           private UdpClient m_udpClient;

           /// <summary>
           /// 服务器实际上在本地机器上监听的
           /// 端口,用于当一台计算机上同时启
           /// 动两个可两以上服务器进程时,标
           /// 识不同的服务器进程
           /// </summary>
           private int m_iMyServerPort;

           /// <summary>
           /// 客户端在本地机器上实际使用的端口,
           /// 用于当一台计算机上同时有两个或两
           /// 个以上客户端进程在运行时,标识不
           /// 同的客户端进程
           /// </summary>
           private int m_iMyClientPort;

           /// <summary>
           /// 标识是否已成功创服务器
           /// </summary>
           private bool m_bServerCreated;

           /// <summary>
           /// 标识是否已成功创建客户端
           /// </summary>
           private bool m_bClientCreated;

           /// <summary>
           /// 服务器使用的线程
           /// </summary>
           private Thread m_serverThread;

           /// <summary>
           /// 客户端使用的线程
           /// </summary>
           private Thread m_clientThread;

           /// <summary>
           /// 打洞线程
           /// </summary>
           //private Thread m_burrowThread;

           /// <summary>
           /// 远端节点
           /// </summary>
           private IPEndPoint m_remotePoint;

           /// <summary>
           /// 当前进程作为客户端的公共终端
           /// </summary>
           private string m_strMyPublicEndPoint;

           /// <summary>
           /// 当前进程作为客户端的私有终端
           /// </summary>
           private string m_strMyPrivateEndPoint;

           /// <summary>
           /// 用于接受信息的StringBuilder实例
           /// </summary>
           private StringBuilder m_sbResponse = new StringBuilder();

           /// <summary>
           /// P2P打洞时标识是否收到回应消息
           /// </summary>
           private bool m_bRecvAck=false ;

           /// <summary>
           /// 请求向其方向打洞的私有终端
           /// </summary>
           private IPEndPoint m_requestPrivateEndPoint;

           /// <summary>
           /// 请求向其方向打洞的公共终端
           /// </summary>
           private IPEndPoint m_requestPublicEndPoint;

           /// <summary>
           /// 打洞消息要发向的节点
           /// </summary>
           private ToEndPoint m_toEndPoint;

           /// <summary>
           /// 用于标识是否已经和请求客户端建立点对连接
           /// </summary>
           //private bool m_bHasConnected=false ;

           /// <summary>
           /// 创建服务器或客户端的最大尝试
           /// 次数,为(65536-60000),防止
           /// 因不能创建而限入死循环或使用
           /// 无效端口
           /// </summary>
           private const int MAX_CREATE_TRY = 5536;

           /// <summary>
           /// 打洞时尝试连接的最大尝试次数
           /// </summary>
           private const int MAX_CONNECT_TRY = 10;


           /// <summary>
           /// 构造函数,初始化UDPP2P实例
           /// </summary>
           public UDPP2PSock()
           {
               m_iMyServerPort = P2PConsts.UDP_SRV_PORT;
               m_iMyClientPort = 60000;
               m_bClientCreated = false;
               m_bServerCreated = false;
               m_toEndPoint = new ToEndPoint();
               m_serverThread = new Thread(new ThreadStart(RunUDPServer ));
               m_clientThread = new Thread(new ThreadStart(RunUDPClient ));
               //m_burrowThread = new Thread(new ThreadStart(BurrowProc));
           }

           /// <summary>
           /// 创建UDP服务器
           /// </summary>
           public void CreateUDPSever()
           {
               int iTryNum=0;

               //开始尝试创建服务器
               while (!m_bServerCreated && iTryNum < MAX_CREATE_TRY)
               {
                   try
                   {
                       m_udpServer = new UdpClient(m_iMyServerPort);
                       m_bServerCreated = true;
                   }
                   catch
                   {
                       m_iMyServerPort++;
                       iTryNum++;
                   }
               }

               //创建失败,抛出异常
               if (!m_bServerCreated && iTryNum == MAX_CREATE_TRY)
               {
                   throw new Exception ("创建服务器尝试失败!");
               }
               m_serverThread.Start();
            
           }

           /// <summary>
           /// 创建UDP客户端
           /// </summary>
           /// <param name="strServerIP">服务器IP</param>
           /// <param name="iServerPort">服务器端口</param>
           public void CreateUDPClient(string strServerIP,int iServerPort)
           {
               int iTryNum = 0;

               //开始尝试创建服务器
               while (!m_bClientCreated     && iTryNum < MAX_CREATE_TRY)
               {
                   try
                   {
                       m_udpClient     = new UdpClient(m_iMyClientPort );
                       m_bClientCreated     = true;
                       string strIPAddress = (System.Net.Dns.GetHostAddresses("localhost")[0]).ToString();
                       m_strMyPrivateEndPoint = strIPAddress + ":" + m_iMyClientPort.ToString();
                   }
                   catch
                   {
                       m_iMyClientPort ++;
                       iTryNum++;
                   }
               }

               //创建失败,抛出异常
               if (!m_bClientCreated     && iTryNum == MAX_CREATE_TRY)
               {
                   throw new Exception ("创建客户端尝试失败!");
               }

               IPEndPoint hostPoint = new IPEndPoint(IPAddress.Parse(strServerIP), iServerPort);
               string strLocalIP = (System.Net.Dns.GetHostAddresses("localhost"))[0].ToString();
               SendLocalPoint(strLocalIP, m_iMyClientPort, hostPoint);
               m_clientThread .Start();
           }


           /// <summary>
           /// 运行UDP服务器
           /// </summary>
           private void RunUDPServer()
           {
               while (true)
               {
                   byte[] msgBuffer =m_udpServer .Receive(ref m_remotePoint);
                   m_sbResponse.Append(System.Text.Encoding.Default.GetString(msgBuffer));
                   CheckCommand();
                   Thread.Sleep(10);
               }
           }


           /// <summary>
           /// 运行UDP客户端
           /// </summary>
           private void RunUDPClient()
           {
               while (true)
               {
                   byte[] msgBuffer = m_udpClient.Receive(ref m_remotePoint);
                   m_sbResponse.Append(System.Text.Encoding.Default.GetString(msgBuffer));
                   CheckCommand();
                   Thread.Sleep(10);
               }
           }


           /// <summary>
           /// 销毁UDP服务器
           /// </summary>
           public void DisposeUDPServer()
           {
               m_serverThread.Abort();
               m_udpServer.Close();
           }

           /// <summary>
           /// 销毁UDP客房端
           /// </summary>
           public void DisposeUDPClient()
           {
               m_clientThread.Abort();
               m_udpClient.Close();
           }

           /// <summary>
           /// 发送消息
           /// </summary>
           /// <param name="strMsg">消息内容</param>
           /// <param name="REP">接收节点</param>
           public void SendData(string strMsg,IPEndPoint REP)
           {
               byte[] byMsg = System.Text.Encoding.Default.GetBytes(strMsg.ToCharArray());
               m_udpClient.Send(byMsg, byMsg.Length, REP);
           }


           /// <summary>
           /// 发送消息,服务器专用
           /// </summary>
           /// <param name="strMsg">消息内容</param>
           /// <param name="REP">接收节点</param>
           private void ServerSendData(string strMsg,IPEndPoint REP)
           {
               byte[] byMsg = System.Text.Encoding.Default.GetBytes(strMsg.ToCharArray());
               m_udpServer.Send(byMsg, byMsg.Length, REP);
           }


           /// <summary>
           /// 发送本地节点信息
           /// </summary>
           /// <param name="strLocalIP">本地IP</param>
           /// <param name="iLocalPort">本地端口</param>
           public void SendLocalPoint(string strLocalIP, int iLocalPort,IPEndPoint REP)
           {
               string strLocalPoint = "/x01/x02" + strLocalIP + ":" + iLocalPort.ToString() + "/x02/x01";
               SendData(strLocalPoint, REP);
           }

/// <summary>
          /// 同时向指定的终端(包括公共终端和私有终端)打洞
          /// </summary>
          /// <param name="pubEndPoint">公共终端</param>
          /// <param name="prEndPoint">私有终端</param>
          /// <returns>打洞成功返回true,否则返回false</returns>
          public void StartBurrowTo(IPEndPoint pubEndPoint, IPEndPoint prEndPoint)
          {
              Thread burrowThread = new Thread(new ThreadStart(BurrowProc));
              m_toEndPoint.m_privateEndPoint = prEndPoint;
              m_toEndPoint.m_publicEndPoint = pubEndPoint;
              burrowThread.Start();
          }

        
          /// <summary>
          /// 打洞线程
          /// </summary>
          private void BurrowProc()
          {
              IPEndPoint prEndPoint = m_toEndPoint.m_privateEndPoint;
              IPEndPoint pubEndPoint = m_toEndPoint.m_publicEndPoint;
              int j = 0;
              for (int i = 0; i < MAX_CONNECT_TRY; i++)
              {
                  SendData("/x01/x07/x07/x01", prEndPoint);
                  SendData("/x01/x07/x07/x01", pubEndPoint);

                  //等待接收线程标记修改
                  for (j = 0; j < MAX_CONNECT_TRY; j++)
                  {
                      if (m_bRecvAck)
                      {
                          m_bRecvAck = false;
                          SendData("/x01/x07/x07/x01", prEndPoint);
                          Thread.Sleep(50);
                          SendData("/x01/x07/x07/x01", pubEndPoint);

                          UDPSockEventArgs args = new UDPSockEventArgs("");
                          args.RemoteEndPoint = pubEndPoint;
                          if (OnNewConnectU != null)
                          {
                              OnNewConnectU(this, args);
                          }
                          //Thread .Sleep (System .Threading.Timeout .Infinite );
                          return;
                      }
                      else
                      {
                          Thread.Sleep(100);
                      }
                  }

                  //如果没有收到目标主机的回应,表明本次打
                  //洞尝试失败,等待100毫秒后尝试下一次打洞
                  Thread.Sleep(100);
              }

              //MAX_CONNECT_TRY尝试都失败,表明打洞失败,抛出异常
              //throw new Exception("打洞失败!");
              System.Windows.Forms.MessageBox.Show("打洞失败!");
          }
         

          /// <summary>
          /// 转发打洞请求消息,在服务器端使用
          /// </summary>
          /// <param name="strSrcPrEndpoint">请求转发的源私有终端</param>
          /// <param name="strSrcPubEndPoint">请求转发的源公共终端</param>
          /// <param name="REP">转发消息到达的目的终端</param>
          public void SendBurrowRequest(string strSrcPrEndpoint, string strSrcPubEndPoint,IPEndPoint REP)
          {
              string strBurrowMsg = "/x04/x07" + strSrcPrEndpoint + " " + strSrcPubEndPoint + "/x07/x04";
              ServerSendData(strBurrowMsg, REP);
          }


          /// <summary>
          /// 检查字符串中的命令
          /// </summary>
          private void CheckCommand()
          {
              int nPos;
              string strCmd = m_sbResponse.ToString();

              //如果接收远端用户名
              if ((nPos = strCmd.IndexOf("/x01/x02")) > -1)
              {
                  ReceiveName(strCmd, nPos);
                
                  //反馈公共终给端远端主机
                  string strPubEPMsg = "/x03/x07" + m_remotePoint.ToString() + "/x07/x03";
                  SendData(strPubEPMsg, m_remotePoint);

                  return;
              }

              //如果接收我的公共终端
              if ((nPos = strCmd.IndexOf("/x03/x07")) > -1)
              {
                  ReceiveMyPublicEndPoint(strCmd, nPos);
                  return;
              }

              //如果是打洞请求消息
              if ((nPos = strCmd.IndexOf("/x04/x07")) > -1)
              {
                  ReceiveAndSendAck(strCmd, nPos);
                  return;
              }

              //如果是打洞回应消息
              if ((nPos =strCmd .IndexOf ("/x01/x07"))>-1)
              {
                  m_bRecvAck = true;
                  int nPos2 = strCmd.IndexOf("/x07/x01");
                  if (nPos2 > -1)
                  {
                      m_sbResponse.Remove(nPos, nPos2 - nPos + 2);
                  }

                  /*
                  if (m_requestPublicEndPoint != null)
                  {
                      if (!m_bHasConnected)
                      {
                          m_bHasConnected = true;
                          UDPSockEventArgs args = new UDPSockEventArgs("");
                          args.RemoteEndPoint = m_requestPublicEndPoint;
                          if (OnNewConnectU != null)
                          {
                              OnNewConnectU(this, args);
                          }
                          m_requestPublicEndPoint = null;
                      }
                  }*/

                  return;
              }

              //一般聊天消息
              m_sbResponse.Remove(0, strCmd.Length);
              RaiseMessageEvent(strCmd);
          }


          /// <summary>
          /// 接收远端用户名
          /// </summary>
          /// <param name="strCmd">包含用户名的控制信息</param>
          /// <param name="nPos"></param>
          private void ReceiveName(string strCmd, int nPos)
          {
              int nPos2 = strCmd.IndexOf("/x02/x01");
              if (nPos2 == -1)
              {
                  return;
              }
              m_sbResponse.Remove(nPos, nPos2 - nPos + 2);

              string strUserName = strCmd.Substring(nPos + 2, nPos2 - nPos - 2);
              UDPSockEventArgs e = new UDPSockEventArgs("");
              e.RemoteUserName = strUserName;
              e.RemoteEndPoint = m_remotePoint;

              //触发用户登录事件
              if (OnUserLogInU != null)
              {
                  OnUserLogInU(this, e);
              }
          }


          /// <summary>
          /// 接收打洞请求的消息并发送回应
          /// </summary>
          /// <param name="strCmd"></param>
          /// <param name="nPos"></param>
          private void ReceiveAndSendAck(string strCmd, int nPos)
          {
              int nPos2 = strCmd.IndexOf("/x07/x04");
              if (nPos2 == -1)
              {
                  return;
              }
              m_sbResponse.Remove(nPos, nPos2 - nPos + 2);

              string strBurrowMsg = strCmd.Substring(nPos + 2, nPos2 - nPos - 2);

              string[] strSrcPoint = strBurrowMsg.Split(' ');

              //分析控制字符串包含的节点信息
              string[] strPrEndPoint = strSrcPoint[0].Split(':');
              string[] strPubEndPoint = strSrcPoint[1].Split(':');
              m_requestPrivateEndPoint    = new IPEndPoint(IPAddress.Parse(strPrEndPoint[0]), int.Parse(strPrEndPoint[1]));
              m_requestPublicEndPoint    = new IPEndPoint(IPAddress.Parse(strPubEndPoint[0]), int.Parse(strPubEndPoint[1]));

              //向请求打洞终端的方向打洞
              StartBurrowTo(m_requestPublicEndPoint, m_requestPrivateEndPoint);
          }


          /// <summary>
          /// 接收我的公共终端
          /// </summary>
          /// <param name="strCmd">包含公共终端的控制信息</param>
          /// <param name="nPos">控制字符串的起始位置</param>
          private void ReceiveMyPublicEndPoint(string strCmd, int nPos)
          {
              int nPos2 = strCmd.IndexOf("/x07/x03");
              if (nPos2 == -1)
              {
                  return;
              }
              m_sbResponse.Remove(nPos, nPos2 - nPos + 2);

              m_strMyPublicEndPoint=strCmd.Substring(nPos + 2, nPos2 - nPos - 2);
          }


          /// <summary>
          /// 触发一般UDP消息事件
          /// </summary>
          /// <param name="strMsg">消息内容</param>
          private void RaiseMessageEvent(string strMsg)
          {
              UDPSockEventArgs args = new UDPSockEventArgs("");
              args.SockMessage = strMsg;
              args.RemoteEndPoint = m_remotePoint;
              if (OnSockMessageU != null)
              {
                  OnSockMessageU(this, args);
              }
          }


          /// <summary>
          /// 获取当前进程作为客户端的公共终端
          /// </summary>
          public string MyPublicEndPoint
          {
              get
              {
                  return m_strMyPublicEndPoint;
              }
          }


          /// <summary>
          /// 获取当前进程作为客户端的私有终端
          /// </summary>
          public string MyPrivateEndPoint
          {
              get
              {
                  return m_strMyPrivateEndPoint;
              }
          }
      }

    
      /// <summary>
      /// 保存打洞消息要发向的节点信息
      /// </summary>
      class ToEndPoint
      {
          /// <summary>
          /// 私有节点
          /// </summary>
          public IPEndPoint m_privateEndPoint;

          /// <summary>
          /// 公共节点
          /// </summary>
          public IPEndPoint m_publicEndPoint;
      }

}

           关于如何使用上述程序包的一些说明:
           主要程序的初始化,参考代码如下:
              //创建UDP服务器和客户端
              try
              {
                  string strServerIP="127.0.0.1"
                  udpSock = new UDPP2PSock();
                  udpSock.OnUserLogInU += new UdpUserLogInDelegate(OnUserLogInU);
                  udpSock.OnNewConnectU += new UdpNewConnectDelegate(OnNewConnectU);
                  udpSock.CreateUDPSever();
                  udpSock.CreateUDPClient(strServerIP, P2PConsts.UDP_SRV_PORT);
              }
              catch (Exception ex)
              {

              }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/389069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NLPPython笔记——WordNet

WordNet是一种面向语义的英语词典&#xff0c;由Princeton大学的心理学家、语言学家和计算机工程师联合设计。它不是光把单词以字母顺序排列&#xff0c;而且按照单词的意义组成一个“单词的网络”。 NLTK库中包含了英语WordNet&#xff0c;里面共有155287个词以及117659个同义…

crc16的c语言函数 计算ccitt_C语言为何如此重要

●●●如今&#xff0c;有很多学生不懂为何要学习编程语言&#xff0c;为何要学习C语言&#xff1f;原因是大学生不能满足于只会用办公软件&#xff0c;而应当有更高的学习要求&#xff0c;对于理工科的学生尤其如此。计算机的本质是“程序的机器”&#xff0c;程序和指令的思想…

毫米波雷达与激光雷达的初探

毫米波雷达与激光雷达的初探 雷达 &#xff08;Radio Detection and Range, Radar&#xff09;是一种利用电磁波来对目标进行探测和定位的电子设备。实现距离测量、运动参数测量、搜索和发现目标、目标定位、目标特性参数分析等功能。 分类 电磁波按照从低频到高频的顺序&…

aws spark_使用Spark构建AWS数据湖时的一些问题以及如何处理这些问题

aws spark技术提示 (TECHNICAL TIPS) 介绍 (Introduction) At first, it seemed to be quite easy to write down and run a Spark application. If you are experienced with data frame manipulation using pandas, numpy and other packages in Python, and/or the SQL lang…

冲刺第三天 11.27 TUE

任务执行情况 已解决问题 数据库结构已经确定 对联生成model已训练完成 词匹配部分完成 微信前端rush版本完成 总体情况 团队成员今日已完成任务剩余任务困难Dacheng, Weijieazure数据库搭建(完成&#xff09;multiple communication scripts, call APIs需要进行整合调试Yichon…

锁是网络数据库中的一个非常重要的概念

锁是网络数据库中的一个非常重要的概念&#xff0c;它主要用于多用户环境下保证数据库完整性和一致性。各种大型数据库所采用的锁的基本理论是一致的&#xff0c;但在具体 实现上各有差别。目前&#xff0c;大多数数据库管理系统都或多或少具有自我调节、自我管理的功能&#x…

DPDK+Pktgen 高速发包测试

参考博客 Pktgen概述 Pktgen,(Packet Gen-erator)是一个基于DPDK的软件框架&#xff0c;发包速率可达线速。提供运行时管理&#xff0c;端口实时测量。可以控制 UDP, TCP, ARP, ICMP, GRE, MPLS and Queue-in-Queue等包。可以通过TCP进行远程控制。Pktgen官网 安装使用过程 版本…

python 商城api编写_Python实现简单的API接口

1. get方法import jsonfrom urlparse import parse_qsfrom wsgiref.simple_server import make_server# 定义函数&#xff0c;参数是函数的两个参数&#xff0c;都是python本身定义的&#xff0c;默认就行了。def application(environ, start_response):# 定义文件请求的类型和…

opencv (一) 学习通过OpenCV图形界面及基础

opencv 学习通过OpenCV图形界面基础 用的函数有 cv.line(), cv.circle(),cv.rectangle(), cv.ellipse(),cv.putText() 常用参数 img : 想要绘制图形的图片color: 图形的颜色&#xff0c; BGRthickness&#xff1a;厚度lineType: 线的类型&#xff0c; 8-connected、anti-al…

python精进之路 -- open函数

下面是python中builtins文件里对open函数的定义&#xff0c;我将英文按照我的理解翻译成中文&#xff0c;方便以后查看。 def open(file, moder, bufferingNone, encodingNone, errorsNone, newlineNone, closefdTrue): # known special case of open """  …

数据科学家编程能力需要多好_我们不需要这么多的数据科学家

数据科学家编程能力需要多好I have held the title of data scientist in two industries. I’ve interviewed for more than 30 additional data science positions. I’ve been the CTO of a data-centric startup. I’ve done many hours of data science consulting.我曾担…

基于xtrabackup GDIT方式不锁库作主从同步(主主同步同理,反向及可)

1.安装数据同步工具 注&#xff1a;xtrabackup 在数据恢复的时候比mysqldump要快很多&#xff0c;特别是大数据库的时候&#xff0c;但网络传输的内容要多&#xff0c;压缩需要占用时间。 yum install https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.12…

excel表格行列显示十字定位_WPS表格:Excel表格打印时,如何每页都显示标题行?...

电子表格数据很多的时候&#xff0c;要分很多页打印&#xff0c;如何每页都能显示标题行呢&#xff1f;以下表为例&#xff0c;我们在WPS2019中演示如何每页都显示前两行标题行&#xff1f;1.首先点亮顶部的页面布局选项卡。然后点击打印标题或表头按钮。2.在弹出的页面设置对话…

opencv(二) 图片处理

opencv 图片处理 opencv 图片像素操作 取像素点操作设置像素点取图片块分离&#xff0c;合并 b, g, r import numpy as np import cv2 as cvimg cv.imread(/Users/guoyinhuang/Desktop/G77.jpeg)# 获取像素值 px img[348, 120] # 0 是y, 1 是x print(px)blue img[100, 1…

【NLP】语言模型和迁移学习

10.13 Update&#xff1a;最近新出了一个state-of-the-art预训练模型&#xff0c;传送门&#xff1a;李入魔&#xff1a;【NLP】Google BERT详解​zhuanlan.zhihu.com1. 简介长期以来&#xff0c;词向量一直是NLP任务中的主要表征技术。随着2017年底以及2018年初的一系列技术突…

TCPIP传送协议

以下代码实现在客户端查询成绩&#xff08;数据库在服务器端&#xff09;: 客户端&#xff1a; static void Main(string[] args) { string str null; while (str ! Convert.ToString(0)) { Console.WriteLine("…

sql优化技巧_使用这些查询优化技巧成为SQL向导

sql优化技巧成为SQL向导&#xff01; (Become an SQL Wizard!) It turns out storing data by rows and columns is convenient in a lot of situations, so relational databases have remained a cornerstone of data management in businesses across the globe. Structured…

Day 4:集合——迭代器与List接口

Collection-迭代方法 1、toArray() 返回Object类型数据&#xff0c;接收也需要Object对象&#xff01; Object[] toArray(); Collection c new ArrayList(); Object[] arr c.toArray(); 2、iterator() Collection的方法&#xff0c;返回实现Iterator接口的对象&#xff0c;…

oem是代工还是贴牌_代加工和贴牌加工的区别是什么

展开全部代加工就是替别人加工&#xff0c;贴别人的牌子。贴牌加工即商家自己不生产&#xff0c;而是委托其他生产企e68a8462616964757a686964616f31333365663431业生产&#xff0c;而品牌是自己的。拓展资料&#xff1a;OEM(Original Equipment Manufacture)的基本含义是定牌生…

KNN 算法--图像分类算法

KNN 算法–图像分类算法 找到最近的K个邻居&#xff0c;在前k个最近样本中选择最近的占比最高的类别作为预测类别。 给定测试对象&#xff0c;计算它与训练集中每个对象的距离。圈定距离最近的k个训练对象&#xff0c;作为测试对象的邻居。根据这k个紧邻对象所属的类别&#xf…