C# 實現C/S程式的開發
阿新 • • 發佈:2019-02-15
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.Length; i++)
{//將Byte陣列清理
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.Length; 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();
}
}
}