C#聯(lián)合VisionPro實(shí)現(xiàn)TCP/IP通信詳解
TCP/IP(傳輸控制協(xié)議/互聯(lián)網(wǎng)協(xié)議)是一組用于在網(wǎng)絡(luò)上進(jìn)行通信的通信協(xié)議。它是互聯(lián)網(wǎng)和許多局域網(wǎng)的基礎(chǔ),為計(jì)算機(jī)之間的數(shù)據(jù)傳輸提供了可靠性、有序性和錯(cuò)誤檢測(cè)。在軟件開(kāi)發(fā)中,TCP/IP 通信通常用于實(shí)現(xiàn)網(wǎng)絡(luò)應(yīng)用程序之間的數(shù)據(jù)交換。
基于 TCP/IP 的通信通常涉及以下幾個(gè)步驟:
1、建立連接: 通信雙方通過(guò)套接字(socket)建立連接。在 C# 中,你可以使用 TcpClient 類來(lái)創(chuàng)建一個(gè) TCP 客戶端,并使用 TcpListener 類來(lái)創(chuàng)建一個(gè) TCP 服務(wù)器端。
2、發(fā)送和接收數(shù)據(jù): 一旦連接建立,通信雙方可以通過(guò)套接字發(fā)送和接收數(shù)據(jù)。在 C# 中,你可以使用 NetworkStream 類來(lái)發(fā)送和接收數(shù)據(jù)。
3、關(guān)閉連接: 在通信完成后,通信雙方可以通過(guò)關(guān)閉套接字來(lái)斷開(kāi)連接,釋放資源。
代碼展示
using System; using System.Net; //引入支持socket的命名空間 using System.Net.Sockets; using System.Text; using System.Threading; using System.Windows.Forms; namespace TCPIP通信 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //聲明socket需要支持的對(duì)象 public Socket ServerSocket;//監(jiān)聽(tīng) public Socket SocketAccept;//綁定客戶端 public Socket socket;//和客戶端通信 #region 開(kāi)啟監(jiān)聽(tīng) Thread t1;//監(jiān)聽(tīng) Thread t2;//接收 //開(kāi)啟監(jiān)聽(tīng)(監(jiān)聽(tīng)的是客戶端的鏈接) private void button1_Click(object sender, EventArgs e) { //實(shí)例化socket對(duì)象 //參1:綁定一個(gè)ip地址,參2:數(shù)據(jù)流的格式,參3:協(xié)議 ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //準(zhǔn)備ip對(duì)象綁定ip地址 IPAddress ip = IPAddress.Parse(textBox1.Text); //創(chuàng)建端口號(hào) int port = Convert.ToInt32(textBox2.Text); //把輸入的ip和端口傳入到連接中,嘗試鏈接 IPEndPoint iPEndPoint = new IPEndPoint(ip, port); try { //開(kāi)啟服務(wù)器的時(shí)候很容易報(bào)錯(cuò),所有做異常處理 ServerSocket.Bind(iPEndPoint); //開(kāi)啟監(jiān)聽(tīng)(參數(shù)是監(jiān)聽(tīng)的數(shù)量) ServerSocket.Listen(5); //禁用按鈕,避免重復(fù)監(jiān)聽(tīng) button1.Enabled = false; //監(jiān)聽(tīng)是持續(xù)的,所以要在分線程中進(jìn)行 t1 = new Thread(Listen); //設(shè)置成后臺(tái)線程 t1.IsBackground = true; //分線程中開(kāi)始對(duì)socket監(jiān)聽(tīng) t1.Start(ServerSocket); } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void Listen(object o) { SocketAccept = o as Socket; try { //因?yàn)橐掷m(xù)監(jiān)聽(tīng),所以用了while循環(huán) while (true) { //阻塞線程,直到有客戶端進(jìn)來(lái)的時(shí)候才會(huì)往下執(zhí)行 socket = SocketAccept.Accept(); //表示有客戶端進(jìn)來(lái)了,需要顯示到textBox上面 AddMsg(DateTime.Now.ToString("yyyy-mmddHHMMSS") + ":" + socket.RemoteEndPoint + "鏈接成功"); //換行操作 AddMsg("\r\n"); //開(kāi)啟第二個(gè)線程,用來(lái)檢測(cè)客戶端傳遞過(guò)來(lái)的消息 t2 = new Thread(Receive); t2.IsBackground = true; t2.Start(socket); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } //接收消息的方法 private void Receive(object obj) { socket = obj as Socket; try { while (true) { //定義字節(jié),接收數(shù)據(jù) byte[] buffer = new byte[1024 * 1024 * 2]; int r = socket.Receive(buffer); if (r == 0) { break; } string msg = Encoding.Default.GetString(buffer); AddMsg("他說(shuō):" + msg); AddMsg("\r\n"); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void AddMsg(string msg) { //異步處理,否則沒(méi)辦法刷新ui richText.BeginInvoke(new Action<string>(str => { richText.Text += msg; }), msg); } #endregion //發(fā)送消息 private void sendBtn_Click(object sender, EventArgs e) { //首先獲取要發(fā)送的消息 string str = sendText.Text; byte[] buffer = Encoding.Default.GetBytes(str); try { socket.Send(buffer); AddMsg("我說(shuō):" + str); AddMsg("\r\n"); sendText.Clear(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } //關(guān)閉客戶端 private void button2_Click(object sender, EventArgs e) { if (socket != null) { //禁掉socket的接收和發(fā)送 socket.Shutdown(SocketShutdown.Both); socket.Close(); t2.Abort(); } ServerSocket.Close(); SocketAccept.Close(); t1.Abort(); //打開(kāi)監(jiān)聽(tīng)的按鈕 button1.Enabled = true; } } }
TCP客戶端代碼展示
using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Windows.Forms; namespace _5_TCP客戶端 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //描述套字節(jié)對(duì)象 public Socket clientSoket; public Socket socket;//和客戶端通信 //創(chuàng)建一個(gè)線程。 Thread t1;//接收消息 //服務(wù)器鏈接 private void conecBtn_Click(object sender, EventArgs e) { //初始化socket對(duì)象 clientSoket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //綁定IP IPAddress ip = IPAddress.Parse(ipTxt.Text); int port = Convert.ToInt32(portTxt.Text); //形成連接點(diǎn) IPEndPoint iPEndPoint = new IPEndPoint(ip, port); //嘗試與遠(yuǎn)程主機(jī)鏈接 try { clientSoket.Connect(iPEndPoint); AddMsg(DateTime.Now.ToString("HHmmss:") + "鏈接服務(wù)器"); AddMsg("\r\n"); conecBtn.Enabled = false; //開(kāi)啟監(jiān)聽(tīng) t1 = new Thread(Receive); t1.IsBackground = true; t1.Start(clientSoket); } catch (Exception ex) { MessageBox.Show("錯(cuò)誤消息:" + ex.Message); } } //封裝一個(gè)顯示數(shù)據(jù)的方法 private void AddMsg(string msg) { textBox4.BeginInvoke(new Action<string>(str => { textBox4.Text += str; }), msg); } //封裝一個(gè)接收消息的方法 private void Receive(object o) { //當(dāng)前聊天的對(duì)象 Socket clientSocket = o as Socket; while (true) { try { //把字節(jié)轉(zhuǎn)成string byte[] buffer = new byte[1024 * 1024 * 2]; int r = clientSocket.Receive(buffer); if (r == 0) { break; } string msg = Encoding.Default.GetString(buffer); AddMsg("接收到的消息:" + msg); AddMsg("\r\n"); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } //發(fā)送消息 private void sendMsg_Click(object sender, EventArgs e) { byte[] buffer = new byte[1024 * 1024 * 2]; string str = textBox3.Text; //轉(zhuǎn)碼 buffer = Encoding.Default.GetBytes(str); //發(fā) try { clientSoket.Send(buffer); AddMsg(str); AddMsg("\r\n"); textBox3.Clear(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } //斷開(kāi)連接 private void button2_Click(object sender, EventArgs e) { if (clientSoket != null) { //禁掉socket的接收和發(fā)送 clientSoket.Shutdown(SocketShutdown.Both); clientSoket.Close(); t1.Abort(); } t1.Abort(); //打開(kāi)監(jiān)聽(tīng)的按鈕 conecBtn.Enabled = true; } } }
以上就是C#聯(lián)合VisionPro實(shí)現(xiàn)TCP/IP通信詳解的詳細(xì)內(nèi)容,更多關(guān)于C# TCP/IP通信的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解WPF如何顯示具有層級(jí)關(guān)系的數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了在WPF中如何顯示具有層級(jí)關(guān)系的數(shù)據(jù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04C# wpf 實(shí)現(xiàn)窗口任意區(qū)域點(diǎn)擊拖動(dòng)
在wpf要實(shí)現(xiàn)此功能簡(jiǎn)單形式還是比較容易的,但是有一些細(xì)節(jié)需要專門處理,比如與按鈕的點(diǎn)擊事件沖突問(wèn)題,解決事件沖突問(wèn)題后拖動(dòng)的靈敏度,可復(fù)用性等,這篇文章主要介紹了C# wpf 實(shí)現(xiàn)窗口任意區(qū)域點(diǎn)擊拖動(dòng),需要的朋友可以參考下2024-03-03