1. 程式人生 > >簡單的C#TCP協議收發資料示例

簡單的C#TCP協議收發資料示例

參考:http://www.cnblogs.com/jzxx/p/5630516.html

一、原作者的這段話很好,先引用一下:

Socket的Send方法,並非大家想象中的從一個埠傳送訊息到另一個埠,它僅僅是拷貝資料到基礎系統的傳送緩衝區,然後由基礎系統將傳送緩衝區的資料到連線的另一埠。值得一說的是,這裡的拷貝資料與非同步傳送訊息的拷貝是不一樣的,同步傳送的拷貝,是直接拷貝資料到基礎系統緩衝區,拷貝完成後返回,在拷貝的過程中,執行執行緒會IO等待, 此種拷貝與Socket自帶的Buffer空間無關,但非同步傳送訊息的拷貝,是將Socket自帶的Buffer空間內的所有資料,拷貝到基礎系統傳送緩衝區,並立即返回,執行執行緒無需IO等待,所以非同步傳送在傳送前必須執行SetBuffer方法,拷貝完成後,會觸發你自定義回撥函式ProcessSend,在ProcessSend方法中,呼叫SetBuffer方法,重新初始化Buffer空間。

二、程式碼如下:

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); } } }

需要在專案上加兩個TextBox和一個Button(名字分別為 btnSend、txtSendMssg、txtRecvMssg)

三、執行效果(效果圖片見原作者文章)

在傳送資料的文字框中分別輸入“千山鳥飛絕”、“萬徑人蹤滅”、“孤舟蓑笠翁”、“獨釣寒江雪”四句話,輸完一句話,單擊一次“傳送資料”按鈕,就可以在接收資料裡看到這四句話了。上面程式碼中,資訊的傳送時通過TcpClient連線到127.0.0.1的2014埠,資訊的接收是通過Listen函式不斷監聽本機的2014埠實現的。從自己建立的執行緒中修改控制元件資訊,用到了委託。