一、服务器端多线程Socket技术
用TcpListener进行侦听,接受客户端连接,有客户端连进来后开启处理线程处理数据,代码如下:
01.
using
System;
02.
using
System.Threading;
03.
using
System.Net.Sockets;
04.
using
System.Text;
05.
06.
namespace
ConsoleApplication1
07.
{
08.
class
Program
09.
{
10.
static
void
Main(string[] args)
11.
{
12.
// 在8888端口侦听
13.
TcpListener serverSocket =
new
TcpListener(8888);
14.
TcpClient clientSocket =
default
(TcpClient);
15.
int
counter = 0;
16.
17.
serverSocket.Start();
18.
Console.WriteLine(
" >> "
+
"Server Started"
);
19.
20.
counter = 0;
21.
while
(
true
)
22.
{
23.
counter += 1;
24.
// 接受客户端连接
25.
clientSocket = serverSocket.AcceptTcpClient();
26.
Console.WriteLine(
" >> "
+
"Client No:"
+ Convert.ToString(counter) +
" started!"
);
27.
// 启动客户端处理代码
28.
handleClinet client =
new
handleClinet();
29.
client.startClient(clientSocket, Convert.ToString(counter));
30.
}
31.
32.
clientSocket.Close();
33.
serverSocket.Stop();
34.
Console.WriteLine(
" >> "
+
"exit"
);
35.
Console.ReadLine();
36.
}
37.
}
38.
39.
// 客户端连接处理类
40.
public
class
handleClinet
41.
{
42.
TcpClient clientSocket;
43.
string clNo;
44.
45.
public
void
startClient(TcpClient inClientSocket, string clineNo)
46.
{
47.
this
.clientSocket = inClientSocket;
48.
this
.clNo = clineNo;
49.
// 开启处理线程
50.
Thread ctThread =
new
Thread(doChat);
51.
ctThread.Start();
52.
}
53.
54.
private
void
doChat()
55.
{
56.
int
requestCount = 0;
57.
byte[] bytesFrom =
new
byte[10025];
58.
string dataFromClient = null;
59.
Byte[] sendBytes = null;
60.
string serverResponse = null;
61.
string rCount = null;
62.
requestCount = 0;
63.
64.
while
((
true
))
65.
{
66.
try
67.
{
68.
requestCount = requestCount + 1;
69.
70.
// 读取内容
71.
NetworkStream networkStream = clientSocket.GetStream();
72.
networkStream.Read(bytesFrom, 0, (
int
)clientSocket.ReceiveBufferSize);
73.
dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
74.
dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf(
"$"
));
75.
Console.WriteLine(
" >> "
+
"From client-"
+ clNo + dataFromClient);
76.
77.
rCount = Convert.ToString(requestCount);
78.
serverResponse =
"Server to clinet("
+ clNo +
") "
+ rCount;
79.
sendBytes = Encoding.ASCII.GetBytes(serverResponse);
80.
networkStream.Write(sendBytes, 0, sendBytes.Length);
81.
networkStream.Flush();
82.
Console.WriteLine(
" >> "
+ serverResponse);
83.
}
84.
catch
(Exception ex)
85.
{
86.
Console.WriteLine(
" >> "
+ ex.ToString());
87.
}
88.
}
89.
}
90.
}
91.
}
二、鼠标控制技术
鼠标的控制用到了 mouse_event 这个API函数,参考代码如下:
01.
using
System;
02.
using
System.Threading;
03.
using
System.Runtime.InteropServices;
04.
using
System.Windows.Forms;
05.
06.
namespace
MouseControl
07.
{
08.
class
MouseControl
09.
{
10.
///
11.
/// 鼠标控制参数
12.
///
13.
const
int
MOUSEEVENTF_LEFTDOWN = 0x2;
14.
const
int
MOUSEEVENTF_LEFTUP = 0x4;
15.
const
int
MOUSEEVENTF_MIDDLEDOWN = 0x20;
16.
const
int
MOUSEEVENTF_MIDDLEUP = 0x40;
17.
const
int
MOUSEEVENTF_MOVE = 0x1;
18.
const
int
MOUSEEVENTF_ABSOLUTE = 0x8000;
19.
const
int
MOUSEEVENTF_RIGHTDOWN = 0x8;
20.
const
int
MOUSEEVENTF_RIGHTUP = 0x10;
21.
22.
///
23.
/// 鼠标的位置
24.
///
25.
public
struct
PONITAPI
26.
{
27.
public
int
x, y;
28.
}
29.
30.
[DllImport(
"user32.dll"
)]
31.
public
static
extern
int
GetCursorPos(ref PONITAPI p);
32.
33.
[DllImport(
"user32.dll"
)]
34.
public
static
extern
int
SetCursorPos(
int
x,
int
y);
35.
36.
[DllImport(
"user32.dll"
)]
37.
public
static
extern
int
mouse_event(
int
dwFlags,
int
dx,
int
dy,
int
cButtons,
int
dwExtraInfo);
38.
39.
[STAThread]
40.
static
void
Main()
41.
{
42.
PONITAPI p =
new
PONITAPI();
43.
GetCursorPos(ref p);
44.
Console.WriteLine(
"鼠标现在的位置X:{0}, Y:{1}"
, p.x, p.y);
45.
Console.WriteLine(
"Sleep 1 sec..."
);
46.
Thread.Sleep(1000);
47.
48.
p.x = (
new
Random()).Next(Screen.PrimaryScreen.Bounds.Width);
49.
p.y = (
new
Random()).Next(Screen.PrimaryScreen.Bounds.Height);
50.
Console.WriteLine(
"把鼠标移动到X:{0}, Y:{1}"
, p.x, p.y);
51.
SetCursorPos(p.x, p.y);
52.
GetCursorPos(ref p);
53.
Console.WriteLine(
"鼠标现在的位置X:{0}, Y:{1}"
, p.x, p.y);
54.
Console.WriteLine(
"Sleep 1 sec..."
);
55.
Thread.Sleep(1000);
56.
57.
Console.WriteLine(
"在X:{0}, Y:{1} 按下鼠标左键"
, p.x, p.y);
58.
mouse_event(MOUSEEVENTF_LEFTDOWN, p.x, p.y, 0, 0);
59.
Console.WriteLine(
"Sleep 1 sec..."
);
60.
Thread.Sleep(1000);
61.
62.
Console.WriteLine(
"在X:{0}, Y:{1} 释放鼠标左键"
, p.x, p.y);
63.
mouse_event(MOUSEEVENTF_LEFTUP, p.x, p.y, 0, 0);
64.
Console.WriteLine(
"程序结束,按任意键退出...."
);
65.
Console.ReadKey();
66.
}
67.
}
68.
}
三、键盘控制技术
键盘的控制用到了 keybd_event 这个API函数,参考代码段如下:
01.
[DllImport(
"user32.dll"
, EntryPoint =
"keybd_event"
)]
02.
public
static
extern
void
keybd_event(
03.
byte bVk,
04.
byte bScan,
05.
int
dwFlags,
06.
int
dwExtraInfo
07.
);
08.
09.
keybd_event((byte)Keys.F11, 0, 0, 0);
//按下F11
10.
keybd_event((byte)Keys.F11, 0, 0x2, 0);
//弹起F11
四、运行程序
4.1
01.
public
static
void
RunProcess(string name, string command)
02.
{
03.
Process myProcess =
new
Process();
04.
05.
myProcess.StartInfo.FileName = name;
06.
myProcess.StartInfo.Arguments = command;
07.
myProcess.Start();
08.
return
;
09.
}
4.2 运行CMD并取得命令执行结果
01.
public
static
string RunCmd(string command)
//运行一个cmd命令
02.
{
03.
Process p =
new
Process();
04.
05.
//p.StartInfo.WorkingDirectory = "c:\\"; // 工作目录
06.
p.StartInfo.FileName =
"cmd.exe"
;
// 程序名
07.
p.StartInfo.Arguments =
"/c "
+ command;
// 执行参数
08.
p.StartInfo.UseShellExecute =
false
;
// 关闭Shell的使用
09.
p.StartInfo.RedirectStandardInput =
true
;
// 重定向标准输入
10.
p.StartInfo.RedirectStandardOutput =
true
;
// 重定向标准输出
11.
p.StartInfo.RedirectStandardError =
true
;
// 重定向错误输出
12.
p.StartInfo.CreateNoWindow =
true
;
// 设置不显示窗口
13.
14.
p.Start();
//启动
15.
16.
//p.StandardInput.WriteLine(command); // 也可以用这种方式输入要执行的命令
17.
//p.StandardInput.WriteLine("exit"); // 不过要记得加上Exit,要不然下一行执行的时候会出错
18.
19.
return
p.StandardOutput.ReadToEnd();
// 从输出流取得命令执行结果
20.
}
五、取得屏幕拷贝
01.
public
Image GetScreen( )
02.
{
03.
//this.Hide();
04.
IntPtr dc1 = CreateDC(
"DISPLAY"
, null, null, (IntPtr)null);
05.
//创建显示器的DC
06.
Graphics g1 = Graphics.FromHdc(dc1);
07.
//由一个指定设备的句柄创建一个新的Graphics对象
08.
Bitmap MyImage =
new
Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g1);
09.
//根据屏幕大小创建一个与之相同大小的Bitmap对象
10.
Graphics g2 = Graphics.FromImage(MyImage);
11.
//获得屏幕的句柄
12.
IntPtr dc3 = g1.GetHdc();
13.
//获得位图的句柄
14.
IntPtr dc2 = g2.GetHdc();
15.
//把当前屏幕捕获到位图对象中
16.
BitBlt(dc2, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc3, 0, 0, 13369376);
17.
//把当前屏幕拷贝到位图中
18.
g1.ReleaseHdc(dc3);
19.
//释放屏幕句柄
20.
g2.ReleaseHdc(dc2);
21.
//释放位图句柄
22.
return
MyImage;
23.
//this.Show();
24.
}
取得屏幕拷贝的代码直接用了bitmap格式,性能不高,在实际使用中应该考虑进行压缩。