本地EXE中需要带上socket,在网页中用ajax访问本地端口
https://blog.csdn.net/qingdujun/article/details/75856135
全文所涉及的代码参考上面的博客,感谢这位博主提供的思路解决了困扰我半个月的问题
标题为核心思路,下面讲讲如何实现.
实现思路要素:
1/EXE中包含socket监听本地某端口
2/网页中JS利用AJAX对本地该端口发送请求
以下为Socket代码
注:我们公司的要求仅仅是电脑打开EXE后在这台电脑的网页可以实现某个特殊操作
(一开始我们只想到浏览器插件取EXE所在电脑的物理地址/EXE给本地所有浏览器写入cookie/结合优盾,后面想想,走了太多弯路了,因为查询资料时以上都是网络的资料或者是公司以前的案例)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static Socket m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static void OnAccept(IAsyncResult ar)
{
try
{
Socket socket = ar.AsyncState as Socket;
Socket new_client = socket.EndAccept(ar);
socket.BeginAccept(new AsyncCallback(OnAccept), socket);
byte[] recv_buffer = new byte[1024 * 640];
int real_recv = new_client.Receive(recv_buffer);
string recv_request = Encoding.UTF8.GetString(recv_buffer, 0, real_recv);
Console.WriteLine(recv_request);
Resolve(recv_request, new_client);
}
catch
{
}
}
static void Resolve(string request, Socket response)
{
string[] strs = request.Split(new string[] { "\r\n" }, StringSplitOptions.None);
if (strs.Length > 0)
{
string[] items = strs[0].Split(' ');
Dictionary<string, string> param = new Dictionary<string, string>();
if (strs.Contains(""))
{
string post_data = strs[strs.Length - 1];
if (post_data != "")
{
string[] post_datas = post_data.Split('&');
foreach (string s in post_datas)
{
param.Add(s.Split('=')[0], s.Split('=')[1]);
}
}
}
Route(items[1], param, response);
}
}
public static void HomePage(Socket response)
{
string statusline = "HTTP/1.1 200 OK\r\n";
byte[] statusline_to_bytes = Encoding.UTF8.GetBytes(statusline);
string content = "软件已启动";//网页收到的回复值
byte[] content_to_bytes = Encoding.UTF8.GetBytes(content);
string header = string.Format("Access-Control-Allow-Origin:*\r\nContent-Type:text/html;charset=UTF-8\r\nContent-Length:{0}\r\n", content_to_bytes.Length);
byte[] header_to_bytes = Encoding.UTF8.GetBytes(header);
response.Send(statusline_to_bytes);
response.Send(header_to_bytes);
response.Send(new byte[] { (byte)'\r', (byte)'\n' });
response.Send(content_to_bytes);
response.Close();
}
static void Route(string path, Dictionary<string, string> param, Socket response)
{
HomePage(response);
return;
}
static void Main(string[] args)
{
m_socket.Bind(new IPEndPoint(IPAddress.Any, 4231));//4231为端口号
m_socket.Listen(100);
m_socket.BeginAccept(new AsyncCallback(OnAccept), m_socket);
Console.Read();
}
}
}
socket建立之后在网页的JS里写上ajax访问本地端口的代码如下:
$.ajax({
url: 'http://127.0.0.1:4231' ,
type: 'GET',
timeout: 1000,
cache: false,
success: function (result) { //成功执行方法
console.log(result);
if (result == "软件已启动")
{//实现的操作
}
},
error: function (result) {
console.log(result);
{//实现的操作
}
}
});
谨以此博客作为抛砖引玉的例子,所涉及的都是非常简单的知识
当然这样做会有很多问题,想来这套思路也是QQ非常早期的思路了
所以如果你看完之后有更多想法,欢迎在下面讨论
如果正好苦于公司既有EXE又有网页端需要两者结合实现
例如QQ快速登录/本地EXE打开后网页有特殊操作权限的兄弟
可以参考一下本篇例子
我暂时想到的问题有:如果正好本地电脑设定的端口被占用怎么办,
如果有人恶意监听这个端口发现可以实现一些特殊操作怎么办,
当然我们公司的项目提供给的都是不懂代码的客户,客户群体也非常小
有时候老板提出的思路站在客户角度非常合理,站在技术实现角度非常苦手
一口气需要实现二十多个功能,所以这个功能暂时先放在这里了
结语:有时候看起来复杂的问题只是因为我们想复杂了