一、服务器端多线程Socket技术
用TcpListener进行侦听,接受客户端连接,有客户端连进来后开启处理线程处理数据,代码如下: <
xmlnamespace prefix ="o" ns ="urn:schemas-microsoft-com:office:office" />
using System;
using System.Threading;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void < xmlnamespace
prefix ="st1" ns ="urn:schemas-microsoft-com:office:smarttags" />Main(string[] args)
{
// 在8888端口侦听
TcpListener
serverSocket = new TcpListener(8888);
TcpClient
clientSocket = default(TcpClient);
int
counter = 0;
serverSocket.Start();
Console.WriteLine("
>> " + "Server Started");
counter
= 0;
while
(true)
{
counter
+= 1;
// 接受客户端连接
clientSocket
= serverSocket.AcceptTcpClient();
Console.WriteLine("
>> " + "Client No:" + Convert.ToString(counter) + " started!");
// 启动客户端处理代码
handleClinet
client = new handleClinet();
client.startClient(clientSocket,
Convert.ToString(counter));
}
clientSocket.Close();
serverSocket.Stop();
Console.WriteLine("
>> " + "exit");
Console.ReadLine();
}
}
// 客户端连接处理类
public class handleClinet
{
TcpClient clientSocket;
string clNo;
public void startClient(TcpClient
inClientSocket, string clineNo)
{
this.clientSocket
= inClientSocket;
this.clNo
= clineNo;
// 开启处理线程
Thread
ctThread = new Thread(doChat);
ctThread.Start();
}
private void doChat()
{
int
requestCount = 0;
byte[]
bytesFrom = new byte[10025];
string
dataFromClient = null;
Byte[]
sendBytes = null;
string
serverResponse = null;
string
rCount = null;
requestCount
= 0;
while
((true))
{
try
{
requestCount
= requestCount + 1;
// 读取内容
NetworkStream
networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom,
0, (int)clientSocket.ReceiveBufferSize);
dataFromClient
= System.Text.Encoding.ASCII.GetString(bytesFrom);
dataFromClient
= dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
Console.WriteLine("
>> " + "From client-" + clNo + dataFromClient);
rCount
= Convert.ToString(requestCount);
serverResponse
= "Server to clinet(" + clNo + ") " + rCount;
sendBytes
= Encoding.ASCII.GetBytes(serverResponse);
networkStream.Write(sendBytes,
0, sendBytes.Length);
networkStream.Flush();
Console.WriteLine("
>> " + serverResponse);
}
catch
(Exception ex)
{
Console.WriteLine("
>> " + ex.ToString());
}
}
}
}
}
二、鼠标控制技术
鼠标的控制用到了 mouse_event 这个API函数,参考代码如下:
using System;
using System.Threading;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace MouseControl
{
class MouseControl
{
///
/// 鼠标控制参数
///
const int MOUSEEVENTF_LEFTDOWN
= 0x2;
const int MOUSEEVENTF_LEFTUP
= 0x4;
const int MOUSEEVENTF_MIDDLEDOWN
= 0x20;
const int MOUSEEVENTF_MIDDLEUP
= 0x40;
const int MOUSEEVENTF_MOVE
= 0x1;
const int MOUSEEVENTF_ABSOLUTE
= 0x8000;
const int MOUSEEVENTF_RIGHTDOWN
= 0x8;
const int MOUSEEVENTF_RIGHTUP
= 0x10;
///
/// 鼠标的位置
///
public struct PONITAPI
{
public
int x, y;
}
[DllImport("user32.dll")]
public static extern
int GetCursorPos(ref PONITAPI p);
[DllImport("user32.dll")]
public static extern
int SetCursorPos(int x, int y);
[DllImport("user32.dll")]
public static extern
int mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);
[STAThread]
static void Main()
{
PONITAPI
p = new PONITAPI();
GetCursorPos(ref
p);
Console.WriteLine("鼠标现在的位置X:{0},
Y:{1}", p.x, p.y);
Console.WriteLine("Sleep
1 sec...");
Thread.Sleep(1000);
p.x
= (new Random()).Next(Screen.PrimaryScreen.Bounds.Width);
p.y
= (new Random()).Next(Screen.PrimaryScreen.Bounds.Height);
Console.WriteLine("把鼠标移动到X:{0},
Y:{1}", p.x, p.y);
SetCursorPos(p.x,
p.y);
GetCursorPos(ref
p);
Console.WriteLine("鼠标现在的位置X:{0},
Y:{1}", p.x, p.y);
Console.WriteLine("Sleep
1 sec...");
Thread.Sleep(1000);
Console.WriteLine("在X:{0},
Y:{1} 按下鼠标左键", p.x, p.y);
mouse_event(MOUSEEVENTF_LEFTDOWN,
p.x, p.y, 0, 0);
Console.WriteLine("Sleep
1 sec...");
Thread.Sleep(1000);
Console.WriteLine("在X:{0},
Y:{1} 释放鼠标左键", p.x, p.y);
mouse_event(MOUSEEVENTF_LEFTUP,
p.x, p.y, 0, 0);
Console.WriteLine("程序结束,按任意键退出....");
Console.ReadKey();
}
}
}
三、键盘控制技术
键盘的控制用到了 keybd_event 这个API函数,参考代码段如下:
[DllImport("user32.dll", EntryPoint = "keybd_event")]
public static extern void keybd_event(
byte bVk,
byte bScan,
int dwFlags,
int dwExtraInfo
);
keybd_event((byte)Keys.F11, 0, 0, 0);//按下F11
keybd_event((byte)Keys.F11, 0, 0x2, 0); //弹起F11
四、运行程序
4.1
public static void RunProcess(string name, string command)
{
Process myProcess = new Process();
myProcess.StartInfo.FileName = name;
myProcess.StartInfo.Arguments = command;
myProcess.Start();
return;
}
4.2 运行CMD并取得命令执行结果
public static string RunCmd(string command)//运行一个cmd命令
{
Process p = new Process();
//p.StartInfo.WorkingDirectory = "c:\\"; // 工作目录
p.StartInfo.FileName = "cmd.exe"; // 程序名
p.StartInfo.Arguments = "/c " + command; // 执行参数
p.StartInfo.UseShellExecute = false; // 关闭Shell的使用
p.StartInfo.RedirectStandardInput
= true; // 重定向标准输入
p.StartInfo.RedirectStandardOutput
= true; // 重定向标准输出
p.StartInfo.RedirectStandardError
= true; // 重定向错误输出
p.StartInfo.CreateNoWindow = true; // 设置不显示窗口
p.Start(); //启动
//p.StandardInput.WriteLine(command); // 也可以用这种方式输入要执行的命令
//p.StandardInput.WriteLine("exit"); // 不过要记得加上Exit,要不然下一行执行的时候会出错
return p.StandardOutput.ReadToEnd(); // 从输出流取得命令执行结果
}
五、取得屏幕拷贝
public Image GetScreen( )
{
//this.Hide();
IntPtr dc1 = CreateDC("DISPLAY", null,
null, (IntPtr)null);
//创建显示器的DC
Graphics g1 = Graphics.FromHdc(dc1);
//由一个指定设备的句柄创建一个新的Graphics对象
Bitmap MyImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height, g1);
//根据屏幕大小创建一个与之相同大小的Bitmap对象
Graphics g2 = Graphics.FromImage(MyImage);
//获得屏幕的句柄
IntPtr dc3 = g1.GetHdc();
//获得位图的句柄
IntPtr dc2 = g2.GetHdc();
//把当前屏幕捕获到位图对象中
BitBlt(dc2, 0, 0, Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height, dc3, 0, 0, 13369376);
//把当前屏幕拷贝到位图中
g1.ReleaseHdc(dc3);
//释放屏幕句柄
g2.ReleaseHdc(dc2);
//释放位图句柄
return MyImage;
//this.Show();
}
取得屏幕拷贝的代码直接用了bitmap格式,性能不高,在实际使用中应该考虑进行压缩。