文章来自:https://blog.csdn.net/IT_xiao_guang_guang/article/details/104299983


前言

  1.发送手机验证码用的是网建的SMS接口(http://sms.webchinese.cn/

  2.手机验证码简单的做了以下限制:

    ①发送验证码1分钟只能点击发送1次

    ②相同IP手机号码1天最多提交20次(这里我用的是本地局域网IP)

    ③加入图形验证码

  注:SMS官网上的建议还有要对手机号码次数进行限制:单个手机号码30分钟最多提交10次。(这个和IP限制次数方法是一样的,我这里没加)


功能实现

一、功能界面

二、创建图形验证码类

关于图形验证码,也可以参照我的这篇文章:C# WinForm 登录界面的图片验证码


创建产生图形验证码的类:

  ①生成随机验证码字符串,用的是Random随机函数,用GUID生成6位随机数

  ②创建验证码图片,将该字符串画在PictureBox控件中


ImageVeriCodeClass:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;//绘图
using System.Windows.Forms; namespace SMSVeriCode
{
public class ImageVeriCodeClass
{
#region 图片验证码功能
/// <summary>
/// 生成随机验证码字符串
/// </summary>
public static string CreateRandomImageCode(int CodeLength)
{
int randNum;
char code;
string randomCode = String.Empty;//随机验证码 //生成一定长度的随机验证码
//Random random = new Random();//生成随机数对象
for (int i = 0; i < CodeLength; i++)
{
//利用GUID生成6位随机数
byte[] buffer = Guid.NewGuid().ToByteArray();//生成字节数组
int seed = BitConverter.ToInt32(buffer, 0);//利用BitConvert方法把字节数组转换为整数
Random random = new Random(seed);//以生成的整数作为随机种子
randNum = random.Next(); //randNum = random.Next();
if (randNum % 3 == 1)
{
code = (char)('A' + (char)(randNum % 26));//随机大写字母
}
else if (randNum % 3 == 2)
{
code = (char)('a' + (char)(randNum % 26));//随机小写字母
}
else
{
code = (char)('0' + (char)(randNum % 10));//随机数字
}
randomCode += code.ToString();
}
return randomCode;
} /// <summary>
/// 创建验证码图片
/// </summary>
public static void CreateImage(string strValidCode, PictureBox pbox)
{
try
{
int RandAngle = 45;//随机转动角度
int MapWidth = (int)(strValidCode.Length * 21);
Bitmap image = new Bitmap(MapWidth, 28);//验证码图片大小-宽和高 //创建绘图对象Graphics
Graphics graph = Graphics.FromImage(image);
graph.Clear(Color.AliceBlue);//清除绘画面,填充背景色
graph.DrawRectangle(new Pen(Color.Black, 0), 0, 0, image.Width - 1, image.Height - 1);//画一个边框
graph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;//模式
Random rand = new Random();
//背景噪点生成
Pen blackPen = new Pen(Color.LightGray, 0);
for (int i = 0; i < 50; i++)
{
int x = rand.Next(0, image.Width);
int y = rand.Next(0, image.Height);
graph.DrawRectangle(blackPen, x, y, 1, 1);
}
//验证码旋转,防止机器识别
char[] chars = strValidCode.ToCharArray();//拆散字符串成单字符数组
//文字居中
StringFormat format = new StringFormat(StringFormatFlags.NoClip);
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
//定义颜色
Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
//定义字体
string[] font = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋体" };
for (int i = 0; i < chars.Length; i++)
{
int cindex = rand.Next(7);
int findex = rand.Next(5);
Font f = new System.Drawing.Font(font[findex], 13, System.Drawing.FontStyle.Bold);//字体样式(参数2为字体大小)
Brush b = new System.Drawing.SolidBrush(c[cindex]);
Point dot = new Point(16, 16); float angle = rand.Next(-RandAngle, RandAngle);//转动的度数
graph.TranslateTransform(dot.X, dot.Y);//移动光标到指定位置
graph.RotateTransform(angle);
graph.DrawString(chars[i].ToString(), f, b, 1, 1, format); graph.RotateTransform(-angle);//转回去
graph.TranslateTransform(2, -dot.Y);//移动光标到指定位置
}
pbox.Image = image;
}
catch (ArgumentException)
{
MessageBox.Show("验证码图片创建错误");
}
}
#endregion
}
}

三、创建存储IP地址的数据库表

对于IP次数的限制,我是把IP地址存在了数据库的表里。


①先创建一个数据库SMSVeriCode

②创建tIP表的sql语句:

create table tIP
(
IP nvarchar(32), --IP地址
SendTimes int, --发送次数
SMSVeriCodeTime datetime2 --手机验证码发送时间
)

---

四、创建手机验证码类

创建发送手机验证码的类:

  ①发送手机验证码功能

  ②验证国内手机号

  ③根据IP地址限制手机号码1天最多提交20次

  ④获取本地IP地址信息(局域网IP)


SMSVeriCodeClass:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
//需要用到的命名空间
using System.IO;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using System.Net.Sockets; namespace SMSVeriCode
{
public class SMSVeriCodeClass
{
#region 手机验证码功能
/// <summary>
/// 获取随机验证码
/// 利用GUID获取随机数
/// </summary>
/// <param name="Phone">手机号</param>
/// <param name="MinSeed">随机数最小值</param>
/// <param name="MaxSeed">随机数最大值</param>
/// <returns>随机验证码</returns>
public static string GetSMSValidCode(int MinSeed, int MaxSeed)
{
byte[] pbyte = Guid.NewGuid().ToByteArray();//生成字节数组
int seed = BitConverter.ToInt32(pbyte, 0);//利用BitConvert方法把字节数组转换为整数
Random random = new Random(seed);//以生成的整数作为随机种子
string smsVeriCode = random.Next(MinSeed, MaxSeed).ToString(); return smsVeriCode;
} /// <summary>
/// 发送验证码的函数
/// </summary>
/// <param name="Phone"></param>
/// <param name="textContent"></param>
/// <returns>返回发送的结果:数字</returns>
public static string SendSMSVeriCode(string UidName, string KeyMD5, string Phone, string TextContent)
{
string strUrl = "http://utf8.sms.webchinese.cn/?";//UTF-8编码Url
string strUidName = "Uid=";//SMS平台的用户名
string strKeyMD5 = "&key=";//SMS平台的接口密匙;strKeyMD5=接口密钥32位MD5加密(大写)
string strPhone = "&smsMob=";//目的手机号码
string strTextContent = "&smsText="; //短信内容;普通短信70个字/条 strUrl = strUrl + strUidName + UidName + strKeyMD5 + KeyMD5 + strPhone + Phone + strTextContent + TextContent; string SMSResult = GetFromUrl(strUrl);//发送短信,得到返回值
//MessageBox.Show(Result); //string JudgeResult = GetResult(SMSResult);//判断返回值
//return JudgeResult; return SMSResult;
} /// <summary>
/// 发送短信,得到返回值
/// </summary>
public static string GetFromUrl(string url)
{
string strReturn = null; if (url == null || url.Trim().ToString() == "")
{
return strReturn;
}
else//手机号正确
{
string targeturl = url.ToString();
try
{
HttpWebRequest hr = (HttpWebRequest)WebRequest.Create(targeturl);
hr.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)";
hr.Method = "GET";
hr.Timeout = 30 * 60 * 1000; //30分钟超时
WebResponse hs = hr.GetResponse();
Stream sr = hs.GetResponseStream();
StreamReader ser = new StreamReader(sr, Encoding.Default);
strReturn = ser.ReadToEnd();
}
catch (Exception ex)
{
strReturn = null;
MessageBox.Show(ex.Message);
}
}
return strReturn;
} /// <summary>
/// 判断返回值
/// </summary>
public static string GetResult(string strReturn)
{
int result = 0;
try
{
result = int.Parse(strReturn);
switch (result)
{
case -1:
strReturn = "没有该用户账户";
break;
case -2:
strReturn = "接口密钥不正确,不是账户登陆密码";
break;
case -21:
strReturn = "MD5接口密钥加密不正确";
break;
case -3:
strReturn = "短信数量不足";
break;
case -11:
strReturn = "该用户被禁用";
break;
case -14:
strReturn = "短信内容出现非法字符";
break;
case -4:
strReturn = "手机号格式不正确";
break;
case -41:
strReturn = "手机号码为空";
break;
case -42:
strReturn = "短信内容为空";
break;
case -51:
strReturn = "短信签名格式不正确,接口签名格式为:【签名内容】";
break;
case -52:
strReturn = "短信签名太长";
break;
case -6:
strReturn = "IP限制";
break;
default:
strReturn = "成功发送" + result + "条短信!";
break;
}
}
catch (Exception ex)
{
strReturn = ex.Message;
}
return strReturn;
}
#endregion /// <summary>
/// 验证国内手机号
/// </summary>
/// <param name="phone">手机号</param>
/// <returns></returns>
public static bool CheckMobilePhone(string phone)
{
//电信手机号码正则
string dianxin = @"^1[3578][01379]\d{8}$";
Regex dReg = new Regex(dianxin);
//联通手机号正则
string liantong = @"^1[34578][01256]\d{8}$";
Regex tReg = new Regex(liantong);
//移动手机号正则
string yidong = @"^(134[012345678]\d{7}|1[34578][012356789]\d{8})$";
Regex yReg = new Regex(yidong); if (dReg.IsMatch(phone) || tReg.IsMatch(phone) || yReg.IsMatch(phone))
{
return true;
}
return false;
} #region 根据IP限制手机号码1天最多提交20次
/// <summary>
/// 发送次数清零
/// </summary>
public static int ResetSendTimes(string IP)
{
string connString = "server=.;database=SMSVeriCode;uid=test;pwd=test";
SqlConnection pSqlConnection = new SqlConnection(connString);
pSqlConnection.Open(); string sqlReset = "update tIP set SendSMSTimes=0 where IP='" + IP + "'"; SqlCommand sqlcmdReset = new SqlCommand(sqlReset, pSqlConnection); return sqlcmdReset.ExecuteNonQuery();
} /// <summary>
/// 更新已发送的次数
/// </summary>
public static int UpdateSendTimes(string IP)
{
string connString = "server=.;database=SMSVeriCode;uid=test;pwd=test";
SqlConnection pSqlConnection = new SqlConnection(connString);
pSqlConnection.Open(); string sqlUdpate = "update tIP set SendSMSTimes = SendSMSTimes + 1 where IP='" + IP + "'"; SqlCommand sqlcmdUpdate = new SqlCommand(sqlUdpate, pSqlConnection); return sqlcmdUpdate.ExecuteNonQuery();
} /// <summary>
/// 更新手机验证码发送时间
/// </summary>
public static int UpdateSMSCodeTime(string IP)
{
string connString = "server=.;database=SMSVeriCode;uid=test;pwd=test";
SqlConnection pSqlConnection = new SqlConnection(connString);
pSqlConnection.Open(); string sqlUpdateTime = "update tIP set SMSVeriCodeTime=getdate() where IP='" + IP + "'"; SqlCommand sqlcmdUpdateTime = new SqlCommand(sqlUpdateTime, pSqlConnection); return sqlcmdUpdateTime.ExecuteNonQuery();
}
#endregion /// <summary>
/// 获取本地IP地址信息
/// </summary>
public static string GetLocalIP()
{
try
{
string HostName = Dns.GetHostName();//主机名
IPHostEntry ip = Dns.GetHostEntry(HostName); for (int i = 0; i < ip.AddressList.Length; i++)
{
//AddressFamily.InterNetwork表示IPV4
//AddressFamily.InterNetworkV6表示IPV6
if (ip.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
{
return ip.AddressList[i].ToString();
}
}
return "";
}
catch (Exception ex)
{
MessageBox.Show("GetLocalIP Error!" + ex.Message);
return "";
}
}
}
}

五、在Form1中调用以上两个类中的函数,实现功能

注:

  以下代码中的"用户名"和"密钥",要去SMS网站中查看。

string UidName = "XXXXXXX";//SMS平台的用户名
string KeyMD5 = "XXXXXXXX";//SMS平台的接口密匙;

IP次数限制的大致思路——相同IP手机号码1天最多提交20次:

  ①用户发送验证码,获取其IP地址,判断数据表中是否已经有了这个IP;

  如果没有就向数据表中插入这个新的IP地址,接着发送验证码,在表中更新发送次数+1;

  ②如果查询到表中已经有了这个IP地址,就判断其是否满足条件(发送次数<=20,时间<24小时);

  ③如果不满足条件,直接返回,不往下继续执行程序;

  ④如果满足条件,往下执行程序,发送验证码。(同时要注意查询表中的发送次数是否为0,要更新发送时间)

Form1.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace SMSVeriCode
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} #region 图片验证码
private const int ImageVeriCodeLength = 4;//验证码长度
private String strImageVeriCode = "";//验证码 //更新图片验证码
private void UpdateImageVeriCode()
{
strImageVeriCode = ImageVeriCodeClass.CreateRandomImageCode(ImageVeriCodeLength);//生成随机验证码
if (strImageVeriCode == "") return;
ImageVeriCodeClass.CreateImage(strImageVeriCode, pbox1);//创建验证码图片
}
#endregion //窗体加载时更新图片验证码
private void Form1_Load(object sender, EventArgs e)
{
UpdateImageVeriCode();
} //点击PictureBox更新图片验证码
private void pbox1_Click(object sender, EventArgs e)
{
UpdateImageVeriCode();
} /// <summary>
/// 获取手机验证码
/// </summary>
int seconds1 = 60;//倒计时60s
int seconds2 = 60 * 5;//验证码有效时间5分钟
string strSMSVeriCode;
private void btnSendVeriCode_Click(object sender, EventArgs e)
{
//获取文本框中的数据
string phone = txtPhone.Text.Trim();//手机号
string imagevericode = txtImageVeriCode.Text.Trim();//图片验证码 strSMSVeriCode = SMSVeriCodeClass.GetSMSValidCode(100000, 999999);//随机6位SMS验证码
int totalTime = 5;//SMS验证码有效时长
string smsTextContent = "验证码:" + strSMSVeriCode + "," + totalTime + "分钟内有效,请勿泄漏于他人。如非本人操作,请忽略。";//SMS短信文本内容
string UidName = "XXXXXXX";//SMS平台的用户名
string KeyMD5 = "XXXXXXXX";//SMS平台的接口密匙; if (String.IsNullOrEmpty(phone))//判断是否输入了手机号
{
MessageBox.Show("请输入手机号!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
txtPhone.Focus();
}
else if (SMSVeriCodeClass.CheckMobilePhone(phone) == false)//判断手机号格式是否正确
{
MessageBox.Show("请输入有效的11位手机号码", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
txtPhone.Focus();
}
else if (String.IsNullOrEmpty(imagevericode))//判断是否输入了图片验证码
{
MessageBox.Show("请输入图片验证码!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
txtImageVeriCode.Focus();
}
else if (imagevericode.ToLower() != strImageVeriCode.ToLower())//判断图片验证码输入是否正确;不区分大小写
{
MessageBox.Show("您输入的验证码有误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
UpdateImageVeriCode();
txtImageVeriCode.Text = "";
txtImageVeriCode.Focus();
}
else//发送SMS验证码
{
string ip = SMSVeriCodeClass.GetLocalIP(); string connString = "server=.;database=SMSVeriCode;uid=test;pwd=test";
SqlConnection pSqlConnection = new SqlConnection(connString);
pSqlConnection.Open(); string sqlIP = "select *,datediff(hour,SMSVeriCodeTime,getdate()) as TimeIntervel from tIP where IP='" + ip + "'";
SqlCommand sqlcmdIP = new SqlCommand(sqlIP, pSqlConnection);
SqlDataReader sdr = sqlcmdIP.ExecuteReader();
sdr.Read();
if (sdr.HasRows == true)//表中已有此IP地址
{
if (sdr.GetInt32(1) == 20 && sdr.GetInt32(3) <= 24)//20次,24小时
{
MessageBox.Show("相同IP手机号码1天最多提交20次!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
UpdateImageVeriCode();
txtImageVeriCode.Text = "";
return;
}
else if (sdr.GetInt32(1) == 20 && sdr.GetInt32(3) > 24)
{
SMSVeriCodeClass.ResetSendTimes(ip);//发送次数置零
} if (sdr.GetInt32(1) == 0)//次数为0时
{
string SMSResult = SMSVeriCodeClass.SendSMSVeriCode(UidName, KeyMD5, phone, smsTextContent);//发送
if (Convert.ToInt32(SMSResult) > 0)//成功发送SMS验证码
{
//倒计时开始
timer1.Interval = 1000;
timer1.Start();
timer2.Interval = 1000;
timer2.Start(); btnSendVeriCode.Enabled = false;
UpdateImageVeriCode();
txtImageVeriCode.Text = ""; SMSVeriCodeClass.UpdateSendTimes(ip);//更新发送次数+1
SMSVeriCodeClass.UpdateSMSCodeTime(ip);//更新发送时间
}
else//发送SMS验证码失败
{
string JudetResult = SMSVeriCodeClass.GetResult(SMSResult);
MessageBox.Show(JudetResult, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
else
{
string SMSResult = SMSVeriCodeClass.SendSMSVeriCode(UidName, KeyMD5, phone, smsTextContent);//发送
if (Convert.ToInt32(SMSResult) > 0)//成功发送SMS验证码
{
//倒计时开始
timer1.Interval = 1000;
timer1.Start();
timer2.Interval = 1000;
timer2.Start(); btnSendVeriCode.Enabled = false;
UpdateImageVeriCode();
txtImageVeriCode.Text = ""; SMSVeriCodeClass.UpdateSendTimes(ip);//更新发送次数+1
}
else//发送SMS验证码失败
{
string JudetResult = SMSVeriCodeClass.GetResult(SMSResult);
MessageBox.Show(JudetResult, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
else//表中没有此IP地址—第一次发送验证码
{
string smsSendTime = DateTime.Now.ToString();//SMS验证码发送时间 //--------向数据表tIP中添加信息------//
pSqlConnection.Close();
pSqlConnection.Open(); string sqlInsert = "insert into tIP(IP,SendSMSTimes,SMSVeriCodeTime)";
sqlInsert += "values('{0}','{1}','{2}')";
sqlInsert = string.Format(sqlInsert, ip,"0",smsSendTime); SqlCommand sqlcmdInsert = new SqlCommand(sqlInsert, pSqlConnection);
sqlcmdInsert.ExecuteNonQuery(); //--------------发送验证码----------------//
string SMSResult = SMSVeriCodeClass.SendSMSVeriCode(UidName, KeyMD5, phone, smsTextContent);//发送
if (Convert.ToInt32(SMSResult) > 0)//成功发送SMS验证码
{
//倒计时开始
timer1.Interval = 1000;
timer1.Start();
timer2.Interval = 1000;
timer2.Start(); btnSendVeriCode.Enabled = false;
UpdateImageVeriCode();
txtImageVeriCode.Text = ""; SMSVeriCodeClass.UpdateSendTimes(ip);//更新发送次数+1
}
else//发送SMS验证码失败
{
string JudetResult = SMSVeriCodeClass.GetResult(SMSResult);
MessageBox.Show(JudetResult, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
} /// <summary>
/// 倒计时—SMS验证码1分钟只能点击发送1次
/// </summary>
private void timer1_Tick(object sender, EventArgs e)
{
if (seconds1 > 0)
{
seconds1--;
btnSendVeriCode.Text = "剩余" + seconds1.ToString() + "秒";
}
else
{
timer1.Stop(); btnSendVeriCode.Text = "获取验证码";
btnSendVeriCode.Enabled = true;
}
} /// <summary>
/// 手机SMS验证码5分钟内有效;但是如果有新的验证码出现,旧验证码就会失效
/// </summary>
private void timer2_Tick(object sender, EventArgs e)
{
if (seconds2 == 0)
{
timer2.Stop(); //旧的验证码过期,生成一个新的验证码
strSMSVeriCode = SMSVeriCodeClass.GetSMSValidCode(100000, 999999);
}
} /// <summary>
/// 确认按钮
/// </summary>
private void btnConfirm_Click(object sender, EventArgs e)
{
//获取文本数据
string smsvericode = txtSMSVeriCode.Text.Trim();//手机SMS验证码 if (String.IsNullOrEmpty(smsvericode))
{
MessageBox.Show("请输入手机验证码!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
txtSMSVeriCode.Focus();
}
else if (smsvericode != strSMSVeriCode)//判断手机SMS验证码是否输入正确
{
MessageBox.Show("您输入的验证码有误!", "警告", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
txtSMSVeriCode.Focus();
}
else
{
MessageBox.Show("验证成功!");
}
}
}
}

C# WinForm 使用SMS接口发送手机验证码+图形验证码+IP限制的更多相关文章

  1. SNF开发平台WinForm之十二-发送手机短信功能调用-金笛-SNF快速开发平台3.3-Spring.Net.Framework

    1.调用前组装参数 2.调用发送信息服务脚本   .调用前组装参数: BaseSendTaskEntity entity = new BaseSendTaskEntity(); entity.Mess ...

  2. 四:java调接口实现发送手机短信验证码功能

    1.点击获取验证码之前的样式: 2.输入正确的手机号后点击获取验证码之后的样式: 3.如果手机号已经被注册的样式: 4.如果一个手机号一天发送超过3次就提示不能发送: 二:前台的注册页面的代码:reg ...

  3. Java调用WebService接口实现发送手机短信验证码功能,java 手机验证码,WebService接口调用

    近来由于项目需要,需要用到手机短信验证码的功能,其中最主要的是用到了第三方提供的短信平台接口WebService客户端接口,下面我把我在项目中用到的记录一下,以便给大家提供个思路,由于本人的文采有限, ...

  4. Java调用阿里云短信接口发送手机验证码

    前五步可参考阿里云服务文档:https://help.aliyun.com/document_detail/59210.html?spm=a2c4g.11174283.4.1.2b152c42DoJ7 ...

  5. java后台通过Servlet给用户发送手机短信验证码,第一次写勿喷,欢迎转载

    短信验证码跟自己在Servlet画的验证码不一样,我们不用管短信验证码是怎么产生的,我们只需要关注如何调用短信验证码,在短信验证码里面添加 自己需要的随机数或者其他的内容. 现在直接上流程 第一步找一 ...

  6. django之集成阿里云通信(发送手机短信验证码)

    python3 + django2.0 集成 "阿里云通信" 服务: (SDK文档地址:https://help.aliyun.com/document_detail/55491. ...

  7. C# WinForm 使用SMTP协议发送QQ邮箱验证码

    文章来自:https://blog.csdn.net/IT_xiao_guang_guang/article/details/104336604 前言   在程序设计中,发送验证码是常见的一个功能,用 ...

  8. Java实现发送手机验证码功能(短信+语音)

    利用第三方平台可以实现发送手机短信验证码和语音验证码的功能,本文使用框架是struts2+spring+hibernate,现就action层给出核心代码功能. public class Verify ...

  9. 利用java实现的一个发送手机短信的小例子

    今天闲来无事,在微博上看到一个关于用java实现的一个发送手机短信的程序,看了看,写的不太相信,闲的没事,把他整理下来,以后可能用得着 JAVA发送手机短信,流传有几种方法:(1)使用webservi ...

随机推荐

  1. Excel如何快速选定指定区域

    在日常办公中我们经常遇见需要选中指定的区域,这样选种比较快捷节省时间,要比用鼠标下拉要方便很多. 1.框选的是起始的位置(A1) 2.终止位置 3.这就是我们所要选中的区域例如(A1:H21) 总结: ...

  2. Java String类相关知识梳理(含字符串常量池(String Pool)知识)

    目录 1. String类是什么 1.1 定义 1.2 类结构 1.3 所在的包 2. String类的底层数据结构 3. 关于 intern() 方法(重点) 3.1 作用 3.2 字符串常量池(S ...

  3. Cannot access org.springframework.context.ConfigurableApplicationContext

    Cannot access org.springframework.context.ConfigurableApplicationContext 需要将有问题的模块  删除 后重新导入 即可 IDEA ...

  4. 观察者模式的应用:Winform窗体之间传值

    观察者模式的应用:Winform窗体传值 观察者模式的概念: 定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并更新. 今天我们就学着用一下这个观察者模式,先想象 ...

  5. 「newbee-mall新蜂商城开源啦」1000 Star Get !仓库Star数破千!记录一下

    新蜂商城已经开源了 3 个多月左右的时间,在 2019 年的年末,仓库的 Star 数量冲破了 1000,整理本篇文章的时间是 2020 年 1 月 12 日,目前的 Star 数量是 1180 左右 ...

  6. 【GeneXus】开发移动APP时,如何使用Canvas进行布局?

    当我们开发移动端APP的时候,经常遇到一种布局方式,那就是层级的布局,比如:一张照片我想在照片的上面显示它的名称,但不影响我照片展示的布局大小,也就是这个名称是浮在照片上的,如图: 如果要实现这样的布 ...

  7. 2019-2020春江云暖你先知,CAE/EDA/高校等CloudHPC领域年均复合增长率超21%

    原创: 灵魂工作室 速石科技 我猜,我们是最早和你说春天来了的人. 一年前,我们还在小心谨慎地定义着Cloud HPC,一脸娇羞地拿Novartis 诺华制药在5年前做的案例当作标杆. 不久前,Hyp ...

  8. 最短路变形题目 HDU多校7

    Mr.Quin love fishes so much and Mr.Quin’s city has a nautical system,consisiting of N ports and M sh ...

  9. JavaWeb系统(增删改查、多条件查询功能)

    该系统是一个简单的青年服务管理系统,主要包括了较完整的常用的增删改查以及多条件查询功能,对于初学者有很大帮助. 下面是相关的Java代码.jsp页面.以及数据库的创建和相关表的设计 java代码 首先 ...

  10. MySQL 排名、分组后组内排名、取各组的前几名

    一.排名 /*普通排名:从1开始,顺序往下排*/ AS rank ) r ORDER BY score; /*并列排名:相同的值是相同的排名*/ SELECT cs.* , CASE WHEN @p= ...