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)文章
Unity通過(guò)UGUI的Slider調(diào)整物體顏色
這篇文章主要為大家詳細(xì)介紹了Unity通過(guò)UGUI的Slider調(diào)整物體顏色,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
c#用Treeview實(shí)現(xiàn)FolderBrowerDialog 和動(dòng)態(tài)獲取系統(tǒng)圖標(biāo)(運(yùn)用了Win32 
其實(shí),FolderBrowerDialog 很好用呢,有木有啊親,反正我特別的喜歡,微軟大哥把這個(gè)瀏覽文件夾的東東封裝的多好呀2013-03-03
Ruby創(chuàng)建數(shù)組方法總結(jié)
在本篇文章里小編給大家分享了關(guān)于Ruby創(chuàng)建數(shù)組方法的知識(shí)點(diǎn)內(nèi)容,對(duì)戲有興趣的朋友們學(xué)習(xí)下。2019-01-01
C#借助Spire.Doc for .NET實(shí)現(xiàn)Word段落和文本添加底紋
在日常的 Word 文檔處理中,我們經(jīng)常需要通過(guò)各種視覺(jué)手段來(lái)突出重點(diǎn)信息,本文將深入探討如何利用Spire.Doc for .NET實(shí)現(xiàn) Word 段落和文本的底紋效果,感興趣的小伙伴可以了解下2026-02-02
c# 9.0新特性nint和Pattern matching的使用方法
這篇文章主要介紹了c# 9.0新特性nint和Pattern matching的使用方法,文中講解非常細(xì)致,幫助你更好的學(xué)習(xí)c# 9.0,有需求的朋友可以參考下2020-06-06

