C# Tcp協議收發數據


運行這個程序前需要先關閉Windows防火牆,Win7系統關閉防火牆的方法是在控制面板的“控制面板\系統和安全\Windows 防火牆\自定義設置”路徑中,將“家庭或工作(專用)網絡位置設置”和“公用網絡位置設置”下面的選項都選到“關閉Windows防火牆(不推薦)”。

1.界面設計

左側為發送數據的輸入框,單擊“發送數據”把數據發送到指定IP地址的指定端口號。(本例中,IP地址和端口號都被寫死到代碼中)

2.程序代碼

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; namespace TcpClientTest { public partial class FormMain : Form { public FormMain() { InitializeComponent(); } private void FormMain_Load(object sender, EventArgs e) { //初始化控件 txtSendMssg.Text = "測試數據"; //打開Listener開始監聽 Thread thrListener = new Thread(new ThreadStart(Listen)); thrListener.Start(); } private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { //強制關閉程序(強行終止Listener) Environment.Exit(0); } //發送數據 private void btnSend_Click(object sender, EventArgs e) { TcpClient tcpClient = new TcpClient(); //tcpClient.Connect(IPAddress.Parse("170.0.0.78"), 2014); tcpClient.Connect(IPAddress.Parse("127.0.0.1"), 2014); NetworkStream ntwStream = tcpClient.GetStream(); if (ntwStream.CanWrite) { Byte[] bytSend = Encoding.UTF8.GetBytes(txtSendMssg.Text); ntwStream.Write(bytSend, 0, bytSend.Length); } else { MessageBox.Show("無法寫入數據流"); ntwStream.Close(); tcpClient.Close(); return; } ntwStream.Close(); tcpClient.Close(); } //監聽數據 private void Listen() { Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listener.Bind(new IPEndPoint(IPAddress.Any, 2014)); //不斷監聽端口 while (true) { listener.Listen(0); Socket socket = listener.Accept(); NetworkStream ntwStream = new NetworkStream(socket); StreamReader strmReader = new StreamReader(ntwStream); Invoke(new PrintRecvMssgDelegate(PrintRecvMssg), new object[] { strmReader.ReadToEnd() }); socket.Close(); } //程序的listener一直不關閉 //listener.Close(); } //線程內向文本框txtRecvMssg中添加字符串及委托 private delegate void PrintRecvMssgDelegate(string s); private void PrintRecvMssg(string info) { txtRecvMssg.Text += string.Format("[{0}]:{1}\r\n", DateTime.Now.ToLongTimeString(), info); } } }

3.運行效果

在發送數據的文本框中分別輸入“千山鳥飛絕”、“萬徑人蹤滅”、“孤舟蓑笠翁”、“獨釣寒江雪”四句話,輸完一句話,單擊一次“發送數據”按鈕,就可以在接收數據里看到這四句話了。上面代碼中,信息的發送時通過TcpClient連接到127.0.0.1的2014端口,信息的接收是通過Listen函數不斷監聽本機的2014端口實現的。從自己創建的線程中修改控件信息,用到了委托。

END

 

 

Socket的Send方法,並非大家想象中的從一個端口發送消息到另一個端口,它僅僅是拷貝數據到基礎系統的發送緩沖區,然后由基礎系統將發送緩沖區的數據到連接的另一端口。值得一說的是,這里的拷貝數據與異步發送消息的拷貝是不一樣的,同步發送的拷貝,是直接拷貝數據到基礎系統緩沖區,拷貝完成后返回,在拷貝的過程中,執行線程會IO等待, 此種拷貝與Socket自帶的Buffer空間無關,但異步發送消息的拷貝,是將Socket自帶的Buffer空間內的所有數據,拷貝到基礎系統發送緩沖區,並立即返回,執行線程無需IO等待,所以異步發送在發送前必須執行SetBuffer方法,拷貝完成后,會觸發你自定義回調函數ProcessSend,在ProcessSend方法中,調用SetBuffer方法,重新初始化Buffer空間。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM