参考http://bbs.cskin.net/thread-326-1-1.html的大神的代码

socket封装

    /// <summary>/// 自定义Socket对象/// </summary>public class Sockets{/// <summary>/// 空构造/// </summary>public Sockets(){}/// <summary>/// 创建Sockets对象/// </summary>/// <param name="ip">Ip地址</param>/// <param name="client">TcpClient</param>/// <param name="ns">承载客户端Socket的网络流</param>public Sockets(IPEndPoint ip, TcpClient client, NetworkStream ns){Ip = ip;Client = client;nStream = ns;}/// <summary>/// 创建Sockets对象/// </summary>/// <param name="name">用户名</param>/// <param name="pass">密码</param>/// <param name="ip">Ip地址</param>/// <param name="client">TcpClient</param>/// <param name="ns">承载客户端Socket的网络流</param>public Sockets(string name, string pass, IPEndPoint ip, TcpClient client, NetworkStream ns){UserName = name;Password = pass;Ip = ip;Client = client;nStream = ns;}/// <summary>/// 接收缓冲区/// </summary>public byte[] RecBuffer = new byte[8 * 1024];/// <summary>/// 发送缓冲区/// </summary>public byte[] SendBuffer = new byte[8 * 1024];/// <summary>/// 异步接收后包的大小/// </summary>public int Offset { get; set; }/// <summary>/// 用户名/// </summary>public string UserName { get; set; }/// <summary>/// 密码/// </summary>public string Password { get; set; }/// <summary>/// 当前IP地址,端口号/// </summary>public IPEndPoint Ip { get; set; }/// <summary>/// 客户端主通信程序/// </summary>public TcpClient Client { get; set; }/// <summary>/// 承载客户端Socket的网络流/// </summary>public NetworkStream nStream { get; set; }/// <summary>/// 发生异常时不为null./// </summary>public Exception ex { get; set; }/// <summary>/// 新客户端标识.如果推送器发现此标识为true,那么认为是客户端上线/// 仅服务端有效/// </summary>public bool NewClientFlag { get; set; }/// <summary>/// 客户端退出标识.如果服务端发现此标识为true,那么认为客户端下线/// 客户端接收此标识时,认为客户端异常./// </summary>public bool ClientDispose { get; set; }}/// <summary>/// Socket基类(抽象类)/// 抽象3个方法,初始化Socket(含一个构造),停止,启动方法./// 此抽象类为TcpServer与TcpClient的基类,前者实现后者抽象方法./// 作用: 纯属闲的蛋疼,不写个OO的我感觉不会写代码了...What The Fuck.../// </summary>public abstract class SocketObject{public abstract void InitSocket(IPAddress ipaddress, int port);public abstract void InitSocket(string ipaddress, int port);public abstract void Start();public abstract void Stop();}

委托传消息

public delegate void PushSockets(Sockets sockets);

服务端

/// <summary>/// Tcp同步服务端,SocketObject继承抽象类/// 服务端采用TcpListener封装./// 使用Semaphore 来控制并发,每次处理5个.最大处理5000 /// </summary>public class TcpServer : SocketObject{public PushSockets pushSockets;bool IsStop = false;object obj = new object();/// <summary>/// 信号量/// </summary>private Semaphore semap = new Semaphore(5, 5000);/// <summary>/// 客户端队列集合/// </summary>public List<Sockets> ClientList = new List<Sockets>();/// <summary>/// 服务端/// </summary>private TcpListener listener;/// <summary>/// 当前IP地址/// </summary>private IPAddress Ipaddress;/// <summary>/// 欢迎消息/// </summary>public string boundary = "";/// <summary>/// 当前监听端口/// </summary>private int Port;/// <summary>/// 当前IP,端口对象/// </summary>private IPEndPoint ip;/// <summary>/// 初始化服务端对象/// </summary>/// <param name="ipaddress">IP地址</param>/// <param name="port">监听端口</param>public override void InitSocket(IPAddress ipaddress, int port){Ipaddress = ipaddress;Port = port;listener = new TcpListener(Ipaddress, Port);}/// <summary>/// 初始化服务端对象/// </summary>/// <param name="ipaddress">IP地址</param>/// <param name="port">监听端口</param>public override void InitSocket(string ipaddress, int port){Ipaddress = IPAddress.Parse(ipaddress);Port = port;ip = new IPEndPoint(Ipaddress, Port);listener = new TcpListener(Ipaddress, Port);}/// <summary>/// 启动监听,并处理连接/// </summary>public override void Start(){try{listener.Start();Thread AccTh = new Thread(new ThreadStart(delegate{while (true){if (IsStop != false){break;}GetAcceptTcpClient();Thread.Sleep(1);}}));AccTh.Start();}catch (SocketException skex){Sockets sks = new Sockets();sks.ex = skex;if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
            }}/// <summary>/// 停止/// </summary>public override void Stop(){if (listener != null){listener.Stop();listener = null;IsStop = true;pushSockets = null;}}/// <summary>/// 等待处理新的连接/// </summary>private void GetAcceptTcpClient(){try{if (listener.Pending()){semap.WaitOne();TcpClient tclient = listener.AcceptTcpClient();//维护客户端队列Socket socket = tclient.Client;NetworkStream stream = new NetworkStream(socket, true); //承载这个SocketSockets sks = new Sockets(tclient.Client.RemoteEndPoint as IPEndPoint, tclient, stream);sks.NewClientFlag = true;//推送新客户端if (pushSockets != null)pushSockets.Invoke(sks);//客户端异步接收sks.nStream.BeginRead(sks.RecBuffer, 0, sks.RecBuffer.Length, new AsyncCallback(EndReader), sks);//加入客户端集合.
                    AddClientList(sks);//主动向客户端发送一条连接成功信息 //if (stream.CanWrite)//{//    if (!string.IsNullOrEmpty(boundary))//    {//        byte[] buffer = Encoding.UTF8.GetBytes(boundary);//        stream.Write(buffer, 0, buffer.Length);//    }//}
                    semap.Release();}}catch{return;}}/// <summary>/// 异步接收发送的信息./// </summary>/// <param name="ir"></param>private void EndReader(IAsyncResult ir){Sockets sks = ir.AsyncState as Sockets;if (sks != null && listener != null){try{if (sks.NewClientFlag || sks.Offset != 0){sks.NewClientFlag = false;sks.Offset = sks.nStream.EndRead(ir);if (pushSockets != null)pushSockets.Invoke(sks);//推送至UIsks.nStream.BeginRead(sks.RecBuffer, 0, sks.RecBuffer.Length, new AsyncCallback(EndReader), sks);}}catch (Exception skex){lock (obj){//移除异常类
                        ClientList.Remove(sks);Sockets sk = sks;sk.ClientDispose = true;//客户端退出sk.ex = skex;if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
                    }}}}/// <summary>/// 加入队列./// </summary>/// <param name="sk"></param>private void AddClientList(Sockets sk){//虽然有信号量,还是用lock增加系数lock (obj){Sockets sockets = ClientList.Find(o => { return o.Ip == sk.Ip; });//如果不存在则添加,否则更新if (sockets == null){ClientList.Add(sk);}else{ClientList.Remove(sockets);ClientList.Add(sk);}}}/// <summary>/// 向所有在线的客户端发送信息./// </summary>/// <param name="SendData">发送的文本</param>public void SendToAll(string SendData){try{Parallel.ForEach(ClientList, new ParallelOptions() { MaxDegreeOfParallelism = 5 }, item =>{if (item != null)SendToClient(item.Ip, SendData);});}catch (Exception ex){//Console.Write(ex.Message);
            }}/// <summary>/// 向某一位客户端发送信息/// </summary>/// <param name="ip">客户端IP+端口地址</param>/// <param name="SendData">发送的数据包</param>public void SendToClient(IPEndPoint ip, string SendData){try{Sockets sks = ClientList.Find(o => { return o.Ip == ip; });if (sks == null || !sks.Client.Connected || sks.ClientDispose){//没有连接时,标识退出Sockets ks = new Sockets();sks.ClientDispose = true;//标识客户端下线sks.ex = new Exception("客户端无连接");if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
                    ClientList.Remove(sks);}if (sks.Client.Connected){//获取当前流进行写入.NetworkStream nStream = sks.nStream;if (nStream.CanWrite){byte[] buffer = Encoding.UTF8.GetBytes(SendData);nStream.Write(buffer, 0, buffer.Length);}else{//避免流被关闭,重新从对象中获取流nStream = sks.Client.GetStream();if (nStream.CanWrite){byte[] buffer = Encoding.UTF8.GetBytes(SendData);nStream.Write(buffer, 0, buffer.Length);}else{//如果还是无法写入,那么认为客户端中断连接.
                            ClientList.Remove(sks);Sockets ks = new Sockets();sks.ClientDispose = true;//如果出现异常,标识客户端下线sks.ex = new Exception("客户端无连接");if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
}}}}catch (Exception skex){Sockets sks = new Sockets();sks.ClientDispose = true;//如果出现异常,标识客户端退出sks.ex = skex;if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
            }}}

客户端

public class TcpClients : SocketObject{public PushSockets pushSockets;bool IsClose = false;/// <summary>/// 当前管理对象/// </summary>
        Sockets sk;/// <summary>/// 客户端/// </summary>
        TcpClient client;/// <summary>/// 当前连接服务端地址/// </summary>
        IPAddress Ipaddress;/// <summary>/// 当前连接服务端端口号/// </summary>int Port;/// <summary>/// 服务端IP+端口/// </summary>
        IPEndPoint ip;/// <summary>/// 发送与接收使用的流/// </summary>
        NetworkStream nStream;/// <summary>/// 初始化Socket/// </summary>/// <param name="ipaddress"></param>/// <param name="port"></param>public override void InitSocket(IPAddress ipaddress, int port){Ipaddress = ipaddress;Port = port;ip = new IPEndPoint(Ipaddress, Port);client = new TcpClient();}/// <summary>/// 初始化Socket/// </summary>/// <param name="ipaddress">ipd地址</param>/// <param name="port">端口</param>public override void InitSocket(string ipaddress, int port){Ipaddress = IPAddress.Parse(ipaddress);Port = port;ip = new IPEndPoint(Ipaddress, Port);client = new TcpClient();}/// <summary>/// 重写Start方法,其实就是连接服务端/// </summary>public override void Start(){Connect();}/// <summary>/// 连接/// </summary>private void Connect(){client.Connect(ip);nStream = new NetworkStream(client.Client, true);sk = new Sockets(ip, client, nStream);sk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);}/// <summary>/// 读取/// </summary>private void EndReader(IAsyncResult ir){Sockets s = ir.AsyncState as Sockets;try{if (s != null){if (IsClose && client == null){sk.nStream.Close();sk.nStream.Dispose();return;}s.Offset = s.nStream.EndRead(ir);if (pushSockets != null)pushSockets.Invoke(s);//推送至UIsk.nStream.BeginRead(sk.RecBuffer, 0, sk.RecBuffer.Length, new AsyncCallback(EndReader), sk);}}catch (Exception skex){Sockets sks = s;sks.ex = skex;sks.ClientDispose = true;if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
            }}/// <summary>/// 停止/// </summary>public override void Stop(){Sockets sks = new Sockets();try{if (client != null){client.Client.Shutdown(SocketShutdown.Both);Thread.Sleep(10);client.Close();IsClose = true;client = null;}else{sks.ex = new Exception("客户端没有初始化.!");}if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
            }catch (Exception ex){sks.ex = ex;}}/// <summary>/// 发送消息/// </summary>public void SendData(string SendData){try{if (client == null || !client.Connected){Sockets sks = new Sockets();sks.ex = new Exception("客户端无连接..");sks.ClientDispose = true;if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
                }if (client.Connected) //如果连接则发送
                {if (nStream == null){nStream = client.GetStream();}byte[] buffer = Encoding.UTF8.GetBytes(SendData);nStream.Write(buffer, 0, buffer.Length);}}catch (Exception skex){Sockets sks = new Sockets();sks.ex = skex;sks.ClientDispose = true;if (pushSockets != null)pushSockets.Invoke(sks);//推送至UI
            }}}

加密消息的类

/// <summary>/// 数据DES加密/// </summary>public class Encrypt{private byte[] iba_mIV = new byte[8];  //向量private byte[] iba_mKey = new byte[8]; //密钥private DESCryptoServiceProvider io_DES = new DESCryptoServiceProvider();public Encrypt(){this.iba_mKey[0] = 0x95;this.iba_mKey[1] = 0xc4;this.iba_mKey[2] = 0xf6;this.iba_mKey[3] = 0x49;this.iba_mKey[4] = 0xac;this.iba_mKey[5] = 0x61;this.iba_mKey[6] = 0xa3;this.iba_mKey[7] = 0xe2;this.iba_mIV[0] = 0xf9;this.iba_mIV[1] = 0x6a;this.iba_mIV[2] = 0x65;this.iba_mIV[3] = 0xb8;this.iba_mIV[4] = 0x4a;this.iba_mIV[5] = 0x23;this.iba_mIV[6] = 0xfe;this.iba_mIV[7] = 0xc6;this.io_DES.Key = this.iba_mKey;this.io_DES.IV = this.iba_mIV;}/// <summary>/// 初始化加密向量与密钥 长度为8/// </summary>/// <param name="iba_mIV">向量</param>/// <param name="iba_mKey">密钥</param>public Encrypt(byte[] iba_mIV, byte[] iba_mKey){this.io_DES.IV = iba_mIV;this.io_DES.Key = iba_mKey;}/// <summary>/// 解密/// </summary>/// <param name="as_Data"></param>/// <returns></returns>public string doDecrypt(string as_Data){ICryptoTransform lo_ICT = this.io_DES.CreateDecryptor(this.io_DES.Key, this.io_DES.IV);try{byte[] lba_bufIn = this.FromHexString(as_Data);//Encoding.UTF8.GetString(Convert.FromBase64String(byte[] lba_bufOut = lo_ICT.TransformFinalBlock(lba_bufIn, 0, lba_bufIn.Length);return Encoding.UTF8.GetString(lba_bufOut);}catch{return as_Data;}}/// <summary>/// 加密/// </summary>/// <param name="as_Data"></param>/// <returns></returns>public string doEncrypt(string as_Data){ICryptoTransform lo_ICT = this.io_DES.CreateEncryptor(this.io_DES.Key, this.io_DES.IV);try{byte[] lba_bufIn = Encoding.UTF8.GetBytes(as_Data);byte[] lba_bufOut = lo_ICT.TransformFinalBlock(lba_bufIn, 0, lba_bufIn.Length);return GetHexString(lba_bufOut);//Convert.ToBase64String(Encoding.UTF8.GetBytes();
            }catch{return "";}}/// <summary>/// 转换2进制/// </summary>/// <param name="as_value"></param>/// <returns></returns>private byte[] FromHexString(string as_value){byte[] lba_buf = new byte[Convert.ToInt32((int)(as_value.Length / 2))];for (int li_i = 0; li_i < lba_buf.Length; li_i++){lba_buf[li_i] = Convert.ToByte(as_value.Substring(li_i * 2, 2), 0x10);}return lba_buf;}/// <summary>/// 字节转字符串/// </summary>/// <param name="aba_buf"></param>/// <returns></returns>private string GetHexString(byte[] aba_buf){StringBuilder lsb_value = new StringBuilder();foreach (byte lb_byte in aba_buf){lsb_value.Append(Convert.ToString(lb_byte, 0x10).PadLeft(2, '0'));}return lsb_value.ToString();}}

cs端控件刷新

public class ControlInvoker{public static void Invoke(Control ctl, ThreadStart thread){try{if (!ctl.IsHandleCreated)return;if (ctl.IsDisposed)return;if (ctl.InvokeRequired){ctl.Invoke(thread);}else{thread();}}catch (Exception ex){Console.Write(ex);}}}

服务端构建

 private TcpServer _server;private void frmSocketServer_Load(object sender, EventArgs e){_server = new TcpServer();_server.pushSockets = Rec;}/// <summary>/// 委托刷新客户数据/// </summary>private void Rec(Sockets sks){ControlInvoker.Invoke(this, new ThreadStart(delegate{//这个是存放消息的,不用管if (txtClientState.Lines.Count() > 10){string path = HandleTxt.CreateFile(AppDomain.CurrentDomain.BaseDirectory + @"log\", DateTime.Now);//创造路径HandleTxt.WriteTxt(path + @"\" + DateTime.Now.ToString("HHmmss") + ".txt", txtClientState.Lines.ToList());txtClientState.Text = "";}if (sks.ex != null){//在此处理异常信息if (sks.ClientDispose){//客户端非主动断开连接下线.  非正常下线  if (sks.Ip != null){RemoveClient(sks, string.Format("客户端:{0}下线.{1}!\r\n", sks.Ip, sks.ex.Message));}}}else{if (sks.NewClientFlag){AddClient(sks, string.Format("新客户端:{0}连接成功.!\r\n", sks.Ip));}else if (sks.Offset == 0){//正常是不会发送0包的,只有客户端主动断开连接时发送空包.//客户端下线.RemoveClient(sks, string.Format("客户端:{0}下线.!\r\n", sks.Ip));}else{//这里是界面提示消息//sks
                    }}}));}/// <summary>/// 接收客户端消息/// </summary>private void ClientInfo(Sockets sks){byte[] buffer = new byte[sks.Offset];Array.Copy(sks.RecBuffer, buffer, sks.Offset);string str = Encoding.UTF8.GetString(buffer);}/// <summary>/// 启动服务/// </summary>private void StartServer(){try{_server.InitSocket(IPAddress.Any, 9527);_server.Start();// ClientState("服务端启动成功.!\r\n");// SetEnabled(false);
            }catch (Exception ex){//ClientState(string.Format("启动失败!原因:{0}", ex.Message));// SetEnabled(true);
            }}/// <summary>/// 发送消息给客户端/// </summary>private void SendToClient(IPEndPoint ip, string SendData){Task.Factory.StartNew(new Action(() =>{Thread.Sleep(1000);_server.SendToClient(ip, SendData);}));}/// <summary>/// 推送消息/// </summary>private void SendMess(){Task.Factory.StartNew(new Action(() =>{_server.SendToAll("123");}));}

客户端接收及发送

private TcpClients _client;
private void frmPlaySingleInfo_Load(object sender, EventArgs e)
{Control.CheckForIllegalCrossThreadCalls = false;_client = new TcpClients();_client.pushSockets = ReceiveMess;//注册推送器
}/// <summary>/// 处理推送过来的消息/// </summary>/// <param name="rec"></param>private void ReceiveMess(Sockets sks){ControlInvoker.Invoke(this, new ThreadStart(delegate{if (sks.ex != null){if (sks.ClientDispose == true){//由于未知原因引发异常.导致客户端下线.   比如网络故障.或服务器断开连接.//SetClientState(string.Format("客户端下线.!异常消息:{0}\r\n", sks.ex));
                    }else{//SetClientState(string.Format("异常消息:{0}\r\n", sks.ex));
                    }//timerConnect.Enabled = true;
                }else if (sks.Offset == 0){//客户端主动下线// SetClientState("客户端下线.!");
                }else{byte[] buffer = new byte[sks.Offset];Array.Copy(sks.RecBuffer, buffer, sks.Offset);string str = Encoding.UTF8.GetString(buffer);if (sks.Client.Client.Available > 0)//判断消息是否发送完成,socket的数据大小限制,分多个包发送
                    {Console.Write(str);_mess += str;}else{_mess += str;//接收完成消息后处理 。。。 _mess = "";}}}));}/// <summary>/// 解析域名/// </summary>private string DomainName(string strDomain){IPHostEntry host = Dns.GetHostByName(strDomain);IPAddress ip = host.AddressList[0];return ip.ToString();}/// <summary>/// 设置端口等数据/// 是否重连/// </summary>private void SetData(PlaySingleXml model, bool isConn){_ip = ExistIp(model.ip);_port = model.port;timer.Interval = model.minutes * 60 * 1000;if (isConn)ConnectSocket();}/// <summary>/// 验证ip地址是否是连接/// </summary>private string ExistIp(string ip){Match m = Regex.Match(ip, @"((\d{1,2})|(1\d{1,2})|(2[0-4]\d)|(25[0-5]))");   // 匹配正则表达式if (!m.Success){return DomainName(ip);}else{return ip;}}/// <summary>/// 连接Socket/// </summary>private void ConnectSocket(){try{_client.InitSocket(_ip, _port);_client.Start();//SetClientState("连接成功.!");//timerConnect.Enabled = false;
            }catch (Exception ex){//SetClientState(ex.Message);//timerConnect.Enabled = true;
            }}

这个socket通讯基本完成

最后再附上另一个大神的东西http://bbs.cskin.net/thread-874-1-1.html

转载于:https://www.cnblogs.com/shuaimeng/p/11009473.html

c#Socket通讯相关推荐

  1. Java与C++Socket通讯注意

    2019独角兽企业重金招聘Python工程师标准>>> c++与java进行socket通信时注意事项 因为java发送的都是网络字节序(big-endium),而c++是主机字节序 ...

  2. [置顶] 【C#】 Socket通讯客户端程序

    这段时间一直在优化Socket通讯这块,经常和Socket打交道,现在分享给大家一个小的案例, 代码如下: byte[] m_dataBuffer = new byte [10];         I ...

  3. java与 C++ 之间进行 SOCKET 通讯要点简要解析

    Endian定义: 在计算机系统体系结构中用来描述在多字节数中各个字节的存储顺序. big-endian也称高位在前.大端在前.是 计算机体系结构中一种描述多字节存储顺序的术语,在这种机制中最重要字节 ...

  4. as3 java 交互_求大佬用 Java 实现这段 AS3 的 socket 通讯功能

    最近在分析一个直播网站,初步分析后发现是在 swf 中用 socket 通讯返回的 flv 地址. 其中 Actionscript socket 通讯的关键代码如下: this._socket = n ...

  5. 基于TCP的Socket通讯

    基于 TCP 的 Socket 通讯 最近要实现两个机器之间基于 TCP 的 socket 通讯(个人使用 Python 实现),尝试了官方的 demo 代码后总是被拒绝连接,仔细研究了一下并成功建立 ...

  6. Socket网络通讯开发总结之:Java 与 C进行Socket通讯

    先交待一下业务应用背景: 服务端:移动交费系统:基于C语言的Unix系统 客户端:增值服务系统:基于Java的软件系统 通迅协议:采用TCP/IP协议,使用TCP以异步方式接入 数据传输:基于Sock ...

  7. c# TCP Socket通讯基础

    在做网络通讯方面的程序时,必不可少的是Socket通讯. 那么我们需要有一套既定的,简易的通讯流程. 如下: <pre name="code" class="csh ...

  8. 试解析Tomcat运行原理(一)--- socket通讯(转)

    关于这篇文章也确实筹划了很久,今天决定开篇写第一篇,说起tomcat首先很容易联想到IIS,因为我最开始使用的就是.net技术,我第一次使用asp写学生成绩管理系统后,很茫然如何让别人都能看到或者说使 ...

  9. socket java 服务器端_Java 简单的Socket通讯的服务器端实现

    最近学安卓开发,看到书上这个Socket通讯的实例,按照书上打的时候客户端一直连接不上,可能是网络问题或者虚拟机连接问题,所以就用控制台实现的客户端,这里是服务器端的.话不多说,直接贴代码 impor ...

  10. Linux网络服务器epoll模型的socket通讯的实现(一)

    准备写一个网络游戏的服务器的通讯模块,参考网上看到的一些代码,在linux下面实现一个多线程的epoll模型的socket通讯的代码,以下是第一部分多线程的切换代码: 1 #include <s ...

最新文章

  1. RSA非对称加密算法Java实现
  2. boost::hana::front用法的测试程序
  3. 将上传图片打上防伪图片水印并写入数据库
  4. AjaxPro怎么用
  5. LeetCode 1806. 还原排列的最少操作步数(模拟)
  6. jq如何在打开新的页面 关闭之前同链接的页面_教你如何“抢”其他域名的权重...
  7. python pyquery库_python解析HTML之:PyQuery库的介绍与使用
  8. c++解析csv 存入数组_Python读写csv文件专题教程(2)
  9. “一键删除中国App”应用海外走红,下载量破500万!谷歌:我先把你删除了
  10. 2019PASS发布以来第一次更新,快点击查看!
  11. PKI体系与CA证书
  12. Tableau同比或环比计算方法
  13. 中文如何翻译成英文?手机中英文一键翻译超简单
  14. 电商物流快递意外延误创意海报设计PSD格式,用心良苦
  15. 论文解读-Intriguing properties of neural networks(ICLR2014)
  16. VmatrixOJ--[H 1003] 小壕的礼物
  17. 计算机ip无法连接打印机,网络打印机无法连接的原因与解决办法-电脑故障
  18. Unity可编程渲染管线系列(六)透明度(裁剪与淡化 Clipping and Fading)
  19. 纳豆红曲胶囊价格作用怎么样!
  20. lol人数最多的服务器,谁说“黑色玫瑰”妹子最多?LOL国服各大服务器趣闻盘点...

热门文章

  1. Validform表单验证框架详解
  2. Validform自定义规则同时校验长度和判重
  3. bagging和boosting算法(集成学习算法)
  4. 轻量的、可自定义 CSS 的 Lightbox 相册插件
  5. 提升教育质量,分班查询系统来助力!
  6. ObjectARX第一课:创建自定义实体
  7. css max-width_CSS中的max-width属性
  8. 【dp】NOI 8787 数的划分
  9. 吞吐量(TPS)、QPS、并发数、响应时间(RT)概念
  10. 白帽SEO,黑帽SEO,灰帽SEO是什么