C# socket 服务端与客户端通信演示代码
主要实现服务端与客户端消息和文件的相互发送,服务端可以控制客户端:重启、关机、注销,截屏(截客户端的屏)。服务端也可向客户端发送闪屏。
服务端:
using System; |
using System.Collections.Generic; |
using System.ComponentModel; |
using System.Data; |
using System.Drawing; |
using System.Net; |
using System.Net.Sockets; |
using System.Text; |
using System.Windows.Forms; |
using System.IO; |
using System.Threading; |
using System.Runtime.InteropServices; |
|
public delegate void DGShowMsg( string strMsg); |
namespace Server |
{ |
public partial class Form1 : Form |
{ |
public Form1() |
{ |
InitializeComponent(); |
TextBox.CheckForIllegalCrossThreadCalls = false ; //关闭跨线程修改控件检查 |
// txtIP.Text = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0].ToString(); |
txtIP.Text = Dns.GetHostByName(Dns.GetHostName()).AddressList[0].ToString(); |
} |
|
[DllImport( "kernel32" )] ///获取系统时间 |
public static extern void GetSystemTime( ref SYSTEMTIME_INFO stinfo); |
|
|
///定义系统时间结构信息 |
[StructLayout(LayoutKind.Sequential)] |
public struct SYSTEMTIME_INFO |
{ |
public ushort wYear; |
public ushort wMonth; |
public ushort wDayOfWeek; |
public ushort wDay; |
public ushort wHour; |
public ushort wMinute; |
public ushort wSecond; |
public ushort wMilliseconds; |
} |
|
Socket sokWatch = null ; //负责监听 客户端段 连接请求的 套接字(女生宿舍的大妈) |
Thread threadWatch = null ; //负责 调用套接字, 执行 监听请求的线程 |
|
//开启监听 按钮 |
private void btnStartListen_Click( object sender, EventArgs e) |
{ |
//实例化 套接字 (ip4寻址协议,流式传输,TCP协议) |
sokWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
|
//创建 ip对象 |
IPAddress address = IPAddress.Parse(txtIP.Text.Trim()); |
// IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList; |
//string ip= this.geta |
//创建网络节点对象 包含 ip和port |
// IPEndPoint endpoint = new IPEndPoint(address, int.Parse(txtPort.Text.Trim())); comboBox1.Text.Trim(); |
IPEndPoint endpoint = new IPEndPoint(address, int .Parse(comboBox1.Text.Trim())); |
//将 监听套接字 绑定到 对应的IP和端口 |
sokWatch.Bind(endpoint); |
//设置 监听队列 长度为10(同时能够处理 10个连接请求) |
sokWatch.Listen(20); |
threadWatch = new Thread(StartWatch); |
threadWatch.IsBackground = true ; |
threadWatch.Start(); |
//txtShow.AppendText("启动服务器成功......rn"); |
label4.Text = "启动服务器成功......" ; |
|
} |
//Dictionary<string, Socket> dictSocket = new Dictionary<string, Socket>(); |
Dictionary< string , ConnectionClient> dictConn = new Dictionary< string , ConnectionClient>(); |
|
bool isWatch = true ; |
|
#region 1.被线程调用 监听连接端口 |
/// <summary> |
/// 被线程调用 监听连接端口 |
/// </summary> |
void StartWatch() |
{ |
string recode; |
while (isWatch) |
{ |
//threadWatch.SetApartmentState(ApartmentState.STA); |
//监听 客户端 连接请求,但是,Accept会阻断当前线程 |
Socket sokMsg = sokWatch.Accept(); //监听到请求,立即创建负责与该客户端套接字通信的套接字 |
ConnectionClient connection = new ConnectionClient(sokMsg, ShowMsg, RemoveClientConnection); |
//将负责与当前连接请求客户端 通信的套接字所在的连接通信类 对象 装入集合 |
dictConn.Add(sokMsg.RemoteEndPoint.ToString(), connection); |
//将 通信套接字 加入 集合,并以通信套接字的远程IpPort作为键 |
//dictSocket.Add(sokMsg.RemoteEndPoint.ToString(), sokMsg); |
//将 通信套接字的 客户端IP端口保存在下拉框里 |
cboClient.Items.Add(sokMsg.RemoteEndPoint.ToString()); |
MessageBox.Show( "有一个客户端新添加!" ); |
recode = sokMsg.RemoteEndPoint.ToString(); |
//调用GetSystemTime函数获取系统时间信息 |
SYSTEMTIME_INFO StInfo; StInfo = new SYSTEMTIME_INFO(); |
GetSystemTime( ref StInfo); |
recode += "子计算机在" +StInfo.wYear.ToString() + "年" + StInfo.wMonth.ToString() + "月" + StInfo.wDay.ToString() + "日" ; |
recode += (StInfo.wHour + 8).ToString() + "点" + StInfo.wMinute.ToString() + "分" + StInfo.wSecond.ToString() + "秒" + "连接服务" ; |
|
//记录每台子计算机连接服务主机的日志 |
StreamWriter m_sw = new StreamWriter(System.Windows.Forms.Application.StartupPath + @"\file.DAT" , true ); |
m_sw.WriteLine(recode); |
m_sw.WriteLine( "------------------------------------------------------------------" ); |
m_sw.Close(); |
//MessageBox.Show(recode); |
dictConn[sokMsg.RemoteEndPoint.ToString()].SendTrue(); |
//启动一个新线程,负责监听该客户端发来的数据 |
//Thread threadConnection = new Thread(ReciveMsg); |
//threadConnection.IsBackground = true; |
//threadConnection.Start(sokMsg); |
|
} |
} |
#endregion |
|
//bool isRec = true; |
//与客户端通信的套接字 是否 监听消息 |
|
#region 发送消息 到指定的客户端 -btnSend_Click |
//发送消息 到指定的客户端 |
|
private void btnSend_Click( object sender, EventArgs e) |
{ |
//byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(txtInput.Text.Trim()); |
//从下拉框中 获得 要哪个客户端发送数据 |
string time; |
string connectionSokKey = cboClient.Text; |
if (! string .IsNullOrEmpty(connectionSokKey)) |
{ |
//从字典集合中根据键获得 负责与该客户端通信的套接字,并调用send方法发送数据过去 |
dictConn[connectionSokKey].Send(txtInput.Text.Trim()); |
SYSTEMTIME_INFO StInfo; StInfo = new SYSTEMTIME_INFO(); |
GetSystemTime( ref StInfo); |
time = StInfo.wYear.ToString() + "/" + StInfo.wMonth.ToString() + "/" + StInfo.wDay.ToString() + " " ; |
time += (StInfo.wHour + 8).ToString() + ":" + StInfo.wMinute.ToString(); |
richTextBox1.AppendText(time + "rn" ); |
richTextBox1.AppendText( "对" + cboClient.Text + "说:" + txtInput.Text.Trim() + "rn" ); |
txtInput.Text = "" ; |
//sokMsg.Send(arrMsg); |
} |
else |
{ |
MessageBox.Show( "请选择要发送的子计算机~~" ); |
} |
} |
#endregion |
|
//发送闪屏 |
private void btnShack_Click( object sender, EventArgs e) |
{ |
string connectionSokKey = cboClient.Text; |
if (! string .IsNullOrEmpty(connectionSokKey)) |
{ |
dictConn[connectionSokKey].SendShake(); |
} |
else |
{ |
MessageBox.Show( "请选择要发送的子计算机~~" ); |
} |
} |
//群闪 |
private void btnShackAll_Click( object sender, EventArgs e) |
{ |
foreach (ConnectionClient conn in dictConn.Values) |
{ |
conn.SendShake(); |
} |
} |
|
#region 2 移除与指定客户端的连接 +void RemoveClientConnection(string key) |
/// <summary> |
/// 移除与指定客户端的连接 |
/// </summary> |
/// <param name="key">指定客户端的IP和端口</param> |
public void RemoveClientConnection( string key) |
{ |
if (dictConn.ContainsKey(key)) |
{ |
dictConn.Remove(key); |
MessageBox.Show(key + "断开连接" ); |
cboClient.Items.Remove(key); |
} |
} |
#endregion |
|
//选择要发送的文件 |
private void btnChooseFile_Click( object sender, EventArgs e) |
{ |
OpenFileDialog ofd = new OpenFileDialog(); |
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) |
{ |
txtFilePath.Text = ofd.FileName; |
} |
} |
|
//发送文件 |
private void btnSendFile_Click( object sender, EventArgs e) |
{ |
//拿到下拉框中选中的客户端IPPORT |
string key = cboClient.Text; |
if (! string .IsNullOrEmpty(key)) |
{ |
dictConn[key].SendFile(txtFilePath.Text.Trim()); |
// txtFilePath.Text = ""; |
} |
else |
{ |
MessageBox.Show( "请选择要发送的子计算机~" ); |
} |
} |
|
#region 向文本框显示消息 -void ShowMsg(string msgStr) |
/// <summary> |
/// 向文本框显示消息 |
/// </summary> |
/// <param name="msgStr">消息</param> |
public void ShowMsg( string msgStr) |
{ |
//MessageBox.Show("1040414"); |
txtShow1.AppendText(msgStr + "rn" ); |
} |
#endregion |
//群消息 |
private void btnSendMsgAll_Click( object sender, EventArgs e) |
{ |
string time; |
foreach (ConnectionClient conn in dictConn.Values) |
{ |
conn.Send(txtInput.Text.Trim()); |
|
} |
SYSTEMTIME_INFO StInfo; StInfo = new SYSTEMTIME_INFO(); |
GetSystemTime( ref StInfo); |
time = StInfo.wYear.ToString() + "/" + StInfo.wMonth.ToString() + "/" + StInfo.wDay.ToString() + " " ; |
time += (StInfo.wHour + 8).ToString() + ":" + StInfo.wMinute.ToString(); |
richTextBox1.AppendText(time + "rn" ); |
richTextBox1.AppendText( "群发消息:" + txtInput.Text.Trim() + "rn" ); |
txtInput.Text = "" ; |
} |
//群发文件 |
private void button1_Click( object sender, EventArgs e) |
{ |
|
foreach (ConnectionClient conn in dictConn.Values) |
{ |
// dictConn.SendFile(txtFilePath.Text.Trim()); |
conn.SendFile(txtFilePath.Text.Trim()); |
|
|
} |
} |
|
private void button2_Click( object sender, EventArgs e) |
{ |
string connectionSokKey = cboClient.Text; |
if (! string .IsNullOrEmpty(connectionSokKey)) |
{ |
dictConn[connectionSokKey].guanji(); |
} |
else |
{ |
MessageBox.Show( "请选择要发送的子计算机~~" ); |
} |
} |
|
private void button3_Click( object sender, EventArgs e) |
{ |
string connectionSokKey = cboClient.Text; |
if (! string .IsNullOrEmpty(connectionSokKey)) |
{ |
dictConn[connectionSokKey].chongqi(); |
} |
else |
{ |
MessageBox.Show( "请选择要发送的子计算机~~" ); |
} |
} |
|
private void button4_Click( object sender, EventArgs e) |
{ |
string connectionSokKey = cboClient.Text; |
if (! string .IsNullOrEmpty(connectionSokKey)) |
{ |
dictConn[connectionSokKey].zhuxiao(); |
} |
else |
{ |
MessageBox.Show( "请选择要发送的子计算机~~" ); |
} |
} |
|
private void button5_Click( object sender, EventArgs e) |
{ |
string connectionSokKey = cboClient.Text; |
if (! string .IsNullOrEmpty(connectionSokKey)) |
{ |
dictConn[connectionSokKey].jieping(); |
} |
else |
{ |
MessageBox.Show( "请选择要发送的子计算机~~" ); |
} |
} |
|
|
|
} |
/////////////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////////////// |
////在这里,我新建了一个与客户端的通信和线程的类(ConnectionClient)////////////////////// |
/// <summary> |
/// 与客户端的 连接通信类(包含了一个 与客户端 通信的 套接字,和线程) |
/// </summary> |
public class ConnectionClient |
{ |
Socket sokMsg; |
DGShowMsg dgShowMsg; //负责 向主窗体文本框显示消息的方法委托 |
DGShowMsg dgRemoveConnection; // 负责 从主窗体 中移除 当前连接 |
Thread threadMsg; |
|
#region 构造函数 |
/// <summary> |
/// |
/// </summary> |
/// <param name="sokMsg">通信套接字</param> |
/// <param name="dgShowMsg">向主窗体文本框显示消息的方法委托</param> |
public ConnectionClient(Socket sokMsg, DGShowMsg dgShowMsg, DGShowMsg dgRemoveConnection) |
{ |
this .sokMsg = sokMsg; |
this .dgShowMsg = dgShowMsg; |
this .dgRemoveConnection = dgRemoveConnection; |
|
this .threadMsg = new Thread(RecMsg); |
this .threadMsg.IsBackground = true ; |
this .threadMsg.Start(); |
} |
#endregion |
|
bool isRec = true ; |
#region 02负责监听客户端发送来的消息 |
void RecMsg() |
{ |
while (isRec) |
{ |
try |
{ |
byte [] arrMsg = new byte [1024 * 1024 * 1]; |
//接收 对应 客户端发来的消息 |
int length = sokMsg.Receive(arrMsg); |
// string abc = Encoding.Default.GetString(arrMsg); |
// MessageBox.Show(abc); |
//将接收到的消息数组里真实消息转成字符串 |
if (arrMsg[0] == 1) |
{ |
//string abc = Encoding.Default.GetString(arrMsg); |
//MessageBox.Show(abc); |
//发送来的是文件 |
//MessageBox.Show("00000s"); |
//SaveFileDialog sfd = new SaveFileDialog(); |
SaveFileDialog sfd = new SaveFileDialog(); |
sfd.Filter = "文本文件(.txt)|*.txt|所有文件(*.*)|*.*" ; |
// MessageBox.Show(sfd.Filter); |
|
//sfd.ShowDialog(); |
//弹出文件保存选择框 |
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) |
{ |
//MessageBox.Show("111110"); |
//创建文件流 |
using (FileStream fs = new FileStream(sfd.FileName, FileMode.OpenOrCreate)) |
{ |
fs.Write(arrMsg, 1, length - 1); |
MessageBox.Show( "文件保存成功!" ); |
} |
} |
} |
/*else if(arrMsg[0] == 2) |
{ |
|
// MemoryStream ms = new MemoryStream(arrMsg, 0, length-1); |
MemoryStream ms = new MemoryStream(arrMsg); |
Image returnImage = Image.FromStream(ms);//?????????? |
PictureBox district = (PictureBox)Application.OpenForms["Form1"].Controls["pictureBox1"].Controls["pictureBox1"]; |
district.Image = returnImage; |
// this.saveFileDialog1.FileName = "";//清空名称栏 |
|
/* |
SaveFileDialog sfd = new SaveFileDialog(); |
sfd.Filter = "图像文件(.jpg)|*.jpg|所有文件(*.*)|*.*"; |
MessageBox.Show(sfd.Filter); |
if (DialogResult.OK == sfd.ShowDialog()) |
{ |
string strFileName = sfd.FileName; |
//Image img = (Image)this.pictureBox1.Image; |
returnImage.Save(strFileName); |
} |
|
}*/ |
else //发送来的是消息 |
{ |
//MessageBox.Show("2222"); |
string strMsg = sokMsg.RemoteEndPoint.ToString()+ "说:" + "rn" +System.Text.Encoding.UTF8.GetString(arrMsg, 0, length); //// 我在这里 Request.ServerVariables.Get("Remote_Addr").ToString()+ |
//通过委托 显示消息到 窗体的文本框 |
dgShowMsg(strMsg); |
} |
|
|
|
//MessageBox.Show("11111"); |
} |
catch (Exception ex) |
{ |
isRec = false ; |
//从主窗体中 移除 下拉框中对应的客户端选择项,同时 移除 集合中对应的 ConnectionClient对象 |
dgRemoveConnection(sokMsg.RemoteEndPoint.ToString()); |
} |
} |
} |
#endregion |
|
#region 03向客户端发送消息 |
/// <summary> |
/// 向客户端发送消息 |
/// </summary> |
/// <param name="strMsg"></param> |
public void Send( string strMsg) |
{ |
byte [] arrMsg = System.Text.Encoding.UTF8.GetBytes(strMsg); |
byte [] arrMsgFinal = new byte [arrMsg.Length + 1]; |
|
arrMsgFinal[0] = 0; //设置 数据标识位等于0,代表 发送的是 文字 |
arrMsg.CopyTo(arrMsgFinal, 1); |
|
sokMsg.Send(arrMsgFinal); |
} |
#endregion |
|
#region 04向客户端发送文件数据 +void SendFile(string strPath) |
/// <summary> |
/// 04向客户端发送文件数据 |
/// </summary> |
/// <param name="strPath">文件路径</param> |
public void SendFile( string strPath) |
{ |
//通过文件流 读取文件内容 |
//MessageBox.Show("12540"); |
using (FileStream fs = new FileStream(strPath, FileMode.OpenOrCreate)) |
{ |
byte [] arrFile = new byte [1024 * 1024 * 2]; |
//读取文件内容到字节数组,并 获得 实际文件大小 |
int length = fs.Read(arrFile, 0, arrFile.Length); |
//定义一个 新数组,长度为文件实际长度 +1 |
byte [] arrFileFina = new byte [length + 1]; |
arrFileFina[0] = 1; //设置 数据标识位等于1,代表 发送的是文件 |
//将 文件数据数组 复制到 新数组中,下标从1开始 |
//arrFile.CopyTo(arrFileFina, 1); |
Buffer.BlockCopy(arrFile, 0, arrFileFina, 1, length); |
// MessageBox.Show("120"); |
//发送文件数据 |
sokMsg.Send(arrFileFina); //, 0, length + 1, SocketFlags.None); |
} |
} |
#endregion |
|
#region 05向客户端发送闪屏 |
/// <summary> |
/// 向客户端发送闪屏 |
/// </summary> |
/// <param name="strMsg"></param> |
public void SendShake() |
{ |
byte [] arrMsgFinal = new byte [1]; |
arrMsgFinal[0] = 2; |
sokMsg.Send(arrMsgFinal); |
} |
#endregion |
|
#region 06关闭与客户端连接 |
/// <summary> |
/// 关闭与客户端连接 |
/// </summary> |
public void CloseConnection() |
{ |
isRec = false ; |
} |
#endregion |
|
#region 07向客户端发送连接成功提示 |
/// <summary> |
/// 向客户端发送连接成功提示 |
/// </summary> |
/// <param name="strMsg"></param> |
public void SendTrue() |
{ |
byte [] arrMsgFinal = new byte [1]; |
arrMsgFinal[0] = 3; |
sokMsg.Send(arrMsgFinal); |
} |
#endregion |
|
#region 08向客户端发送关机命令 |
/// <summary> |
/// 向客户端发送关机命令 |
/// </summary> |
/// <param name="strMsg"></param> |
public void guanji() |
{ |
byte [] arrMsgFinal = new byte [1]; |
arrMsgFinal[0] = 4; |
sokMsg.Send(arrMsgFinal); |
} |
#endregion |
|
#region 09向客户端发送重启命令 |
/// <summary> |
/// 向客户端发送关机命令 |
/// </summary> |
/// <param name="strMsg"></param> |
public void chongqi() |
{ |
byte [] arrMsgFinal = new byte [1]; |
arrMsgFinal[0] = 5; |
sokMsg.Send(arrMsgFinal); |
} |
#endregion |
|
#region 10向客户端发送待机命令 |
/// <summary> |
/// 向客户端发送关机命令 |
/// </summary> |
/// <param name="strMsg"></param> |
public void zhuxiao() |
{ |
byte [] arrMsgFinal = new byte [1]; |
arrMsgFinal[0] = 6; |
sokMsg.Send(arrMsgFinal); |
} |
#endregion |
|
#region 11向客户端发送截屏命令 |
/// <summary> |
/// 向客户端发送截屏命令 |
/// </summary> |
/// <param name="strMsg"></param> |
public void jieping() |
{ |
byte [] arrMsgFinal = new byte [1]; |
arrMsgFinal[0] = 7; |
sokMsg.Send(arrMsgFinal); |
} |
#endregion |
} |
|
} |
|
//该代码片段来自于: http://www.sharejs.com/codes/csharp/6777 |
using System; |
using System.Collections.Generic; |
using System.ComponentModel; |
using System.Data; |
using System.Drawing; |
using System.Net.Sockets; |
using System.Net; |
using System.Threading; |
using System.Windows.Forms; |
using System.IO; |
using System.Text; |
using System.Runtime.InteropServices; |
|
|
public delegate void DGShowMsg( string strMsg); |
namespace Client |
{ |
public partial class Form1 : Form |
{ |
public Form1() |
{ |
InitializeComponent(); |
TextBox.CheckForIllegalCrossThreadCalls = false ; |
|
} |
#region[成员函数] |
///<summary> |
///图像函数 |
///</summary> |
private Image _img; |
#endregion |
[StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
internal struct TokPriv1Luid |
{ |
|
public int Count; |
|
public long Luid; |
|
public int Attr; |
|
} |
|
[DllImport( "kernel32.dll" , ExactSpelling = true )] |
|
internal static extern IntPtr GetCurrentProcess(); |
|
[DllImport( "advapi32.dll" , ExactSpelling = true , SetLastError = true )] |
|
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok); |
|
[DllImport( "advapi32.dll" , SetLastError = true )] |
|
internal static extern bool LookupPrivilegeValue( string host, string name, ref long pluid); |
|
[DllImport( "advapi32.dll" , ExactSpelling = true , SetLastError = true )] |
|
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, |
|
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen); |
|
[DllImport( "user32.dll" , ExactSpelling = true , SetLastError = true )] |
|
internal static extern bool ExitWindowsEx( int flg, int rea); |
|
internal const int SE_PRIVILEGE_ENABLED = 0x00000002; |
|
internal const int TOKEN_QUERY = 0x00000008; |
|
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; |
|
internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege" ; |
|
internal const int EWX_LOGOFF = 0x00000000; //注销 |
|
internal const int EWX_SHUTDOWN = 0x00000001; //关机 |
|
internal const int EWX_REBOOT = 0x00000002; //重启 |
|
internal const int EWX_FORCE = 0x00000004; |
|
internal const int EWX_POWEROFF = 0x00000008; //断开电源 |
|
internal const int EWX_FORCEIFHUNG = 0x00000010; //强制终止未响应的程序 |
|
// internal const int WM_POWERBROADCAST |
|
|
|
private static void DoExitWin( int flg) |
{ |
|
bool ok; |
|
TokPriv1Luid tp; |
|
IntPtr hproc = GetCurrentProcess(); |
|
IntPtr htok = IntPtr.Zero; |
|
ok = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok); |
|
tp.Count = 1; |
|
tp.Luid = 0; |
|
tp.Attr = SE_PRIVILEGE_ENABLED; |
|
ok = LookupPrivilegeValue( null , SE_SHUTDOWN_NAME, ref tp.Luid); |
|
ok = AdjustTokenPrivileges(htok, false , ref tp, 0, IntPtr.Zero, IntPtr.Zero); |
|
ok = ExitWindowsEx(flg, 0); |
|
} |
|
|
Socket sokClient = null ; //负责与服务端通信的套接字 |
Thread threadClient = null ; //负责 监听 服务端发送来的消息的线程 |
bool isRec = true ; //是否循环接收服务端数据 |
// Dictionary<string, ConnectionClient> dictConn = new Dictionary<string, ConnectionClient>(); |
private void btnConnect_Click( object sender, EventArgs e) |
{ |
//实例化 套接字 |
sokClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); |
//创建 ip对象 |
IPAddress address = IPAddress.Parse(txtIP.Text.Trim()); |
//MessageBox.Show("address"); |
//创建网络节点对象 包含 ip和port |
IPEndPoint endpoint = new IPEndPoint(address, int .Parse(comboBox1.Text.Trim())); |
//连接 服务端监听套接字 |
sokClient.Connect(endpoint); |
|
//创建负责接收 服务端发送来数据的 线程 |
threadClient = new Thread(ReceiveMsg); |
threadClient.IsBackground = true ; |
//如果在win7下要通过 某个线程 来调用 文件选择框的代码,就需要设置如下 |
threadClient.SetApartmentState(ApartmentState.STA); |
threadClient.Start(); |
} |
|
|
/// <summary> |
/// 接收服务端发送来的消息数据 |
/// </summary> |
void ReceiveMsg() |
{ |
while (isRec) |
{ |
byte [] msgArr = new byte [1024 * 1024 * 1]; //接收到的消息的缓冲区 |
int length = 0; |
//接收服务端发送来的消息数据 |
length = sokClient.Receive(msgArr); //Receive会阻断线程 |
if (msgArr[0] == 0) //发送来的是文字 |
{ |
string strMsg = System.Text.Encoding.UTF8.GetString(msgArr, 1, length - 1); |
txtShow.AppendText(strMsg + "rn" ); |
} |
else if (msgArr[0] == 1) |
{ |
//发送来的是文件 |
//string abc = Encoding.Default.GetString(msgArr); |
//MessageBox.Show(abc); |
SaveFileDialog sfd = new SaveFileDialog(); |
sfd.Filter = "文本文件(.txt)|*.txt|所有文件(*.*)|*.*" ; |
//弹出文件保存选择框 |
if (sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK) |
{ |
//创建文件流 |
using (FileStream fs = new FileStream(sfd.FileName, FileMode.OpenOrCreate)) |
{ |
fs.Write(msgArr, 1, length - 1); |
MessageBox.Show( "文件保存成功!" ); |
} |
} |
} |
else if (msgArr[0] == 2) |
{ |
ShakeWindow(); |
} |
else if (msgArr[0] == 3) |
{ |
MessageBox.Show( "连接成功" ); |
} |
else if (msgArr[0] == 4) |
{ |
DoExitWin(EWX_SHUTDOWN); |
} |
else if (msgArr[0] == 5) |
{ |
DoExitWin(EWX_REBOOT); |
} |
else if (msgArr[0] == 6) |
{ |
DoExitWin(EWX_LOGOFF); |
} |
else if (msgArr[0] == 7) |
{ |
|
PrintScreen(); |
} |
|
} |
} |
|
#region[方法] |
///<summary> |
///截屏 |
///</summary> |
private void PrintScreen() |
{ |
|
string Opath = @"C:/Picture" ; |
if (Opath.Substring(Opath.Length - 1, 1) != @"/" ) |
Opath = Opath + @"/" ; |
string photoname = DateTime.Now.Ticks.ToString(); |
string path1 = Opath + DateTime.Now.ToShortDateString(); |
if (!Directory.Exists(path1)) |
Directory.CreateDirectory(path1); |
try |
{ |
|
Screen scr = Screen.PrimaryScreen; |
Rectangle rc = scr.Bounds; |
int iWidth = rc.Width; |
int iHeight = rc.Height; |
Bitmap myImage = new Bitmap(iWidth, iHeight); |
Graphics gl = Graphics.FromImage(myImage); |
gl.CopyFromScreen( new Point(0, 0), new Point(0, 0), new Size(iWidth, iHeight)); |
_img = myImage; |
//pictureBox1.Image = _img; |
// IntPtr dc1 = gl.GetHdc(); |
//gl.ReleaseHdc(dc1); |
MessageBox.Show(path1); |
MessageBox.Show(photoname); |
_img.Save(path1 + "//" + photoname + ".jpg" , System.Drawing.Imaging.ImageFormat.Jpeg); |
// _img.Save("D:\1.jpeg"); |
SendFile(path1+ "//" +photoname+ ".jpg" ); |
} |
catch (Exception ex) |
{ |
MessageBox.Show( "截屏失败!n" + ex.Message.ToString() + "n" + ex.StackTrace.ToString()); |
} |
|
// MessageBox.Show("12322222"); |
///////////////////////////////////////////////////////// |
///////////////////发送图片流/////////////////////////// |
/* |
MemoryStream ms = new MemoryStream(); |
byte[] imagedata = null; |
_img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); |
imagedata = ms.GetBuffer(); |
|
byte[] arrFile = new byte[1024 * 1024 * 2]; |
//读取文件内容到字节数组,并 获得 实际文件大小 |
int length = ms.Read(arrFile, 0, arrFile.Length); |
// int length = ms.Read(arrFile, 0, arrFile.Length); |
//定义一个 新数组,长度为文件实际长度 +1 |
byte[] arrFileFina = new byte[length + 1]; |
arrFileFina[0] = 2;//设置 数据标识位等于1,代表 发送的是文件 |
//将 图片流数据数组 复制到 新数组中,下标从1开始 |
//arrFile.CopyTo(arrFileFina, 1); |
Buffer.BlockCopy(arrFile, 0, arrFileFina, 1, length); |
//发送文件数据 |
sokClient.Send(arrFileFina);//, 0, length + 1, SocketFlags.None); |
//MessageBox.Show("我在这里!!!"); |
// byte[] arrMsg = System.Text.Encoding.UTF8.GetBytes(_img); |
MessageBox.Show("2222"); |
*/ |
} |
#endregion |
/* |
private void button1_Click(object sender, EventArgs e) |
{ |
// this.WindowState = FormWindowState.Minimized; |
PrintScreen(); |
if (_img != null) |
{ |
this.pictureBox1.Image = _img; |
} |
this.WindowState = FormWindowState.Normal; |
} |
*/ |
/// <summary> |
/// 闪屏 |
/// </summary> |
private void ShakeWindow() |
{ |
Random ran = new Random(); |
//保存 窗体原坐标 |
System.Drawing.Point point = this .Location; |
for ( int i = 0; i < 30; i++) |
{ |
//随机 坐标 |
this .Location = new System.Drawing.Point(point.X + ran.Next(8), point.Y + ran.Next(8)); |
System.Threading.Thread.Sleep(15); //休息15毫秒 |
this .Location = point; //还原 原坐标(窗体回到原坐标) |
System.Threading.Thread.Sleep(15); //休息15毫秒 |
} |
} |
//发送消息 |
private void btnSend_Click( object sender, EventArgs e) |
{ |
byte [] arrMsg = System.Text.Encoding.UTF8.GetBytes(txtInput.Text.Trim()); |
sokClient.Send(arrMsg); |
richTextBox1.AppendText(txtInput.Text.Trim()+ "rn" ); |
txtInput.Text = "" ; |
} |
|
private void btnChooseFile_Click( object sender, EventArgs e) |
{ |
OpenFileDialog ofd = new OpenFileDialog(); |
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) |
{ |
txtFilePath.Text = ofd.FileName; |
} |
} |
//发送文件 |
private void btnSendFile_Click( object sender, EventArgs e) |
{ |
string key = txtIP.Text + ":" + comboBox1.Text.Trim(); |
//MessageBox.Show(key); |
if (! string .IsNullOrEmpty(key)) |
{ |
SendFile(txtFilePath.Text.Trim()); |
// MessageBox.Show("1230"); |
// txtFilePath.Text = ""; |
} |
} |
private void SendFile( string strPath) |
{ |
//通过文件流 读取文件内容 |
|
using (FileStream fs = new FileStream(strPath, FileMode.OpenOrCreate)) |
{ |
byte [] arrFile = new byte [1024 * 1024 * 2]; |
//读取文件内容到字节数组,并 获得 实际文件大小 |
int length = fs.Read(arrFile, 0, arrFile.Length); |
//定义一个 新数组,长度为文件实际长度 +1 |
byte [] arrFileFina = new byte [length + 1]; |
arrFileFina[0] = 1; //设置 数据标识位等于1,代表 发送的是文件 |
//将 文件数据数组 复制到 新数组中,下标从1开始 |
//arrFile.CopyTo(arrFileFina, 1); |
Buffer.BlockCopy(arrFile, 0, arrFileFina, 1, length); |
//发送文件数据 |
sokClient.Send(arrFileFina); //, 0, length + 1, SocketFlags.None); |
//MessageBox.Show("我在这里!!!"); |
} |
} |
} |
|
} |
//该代码片段来自于: http://www.sharejs.com/codes/csharp/6777 |