核心原理
TCP 建立連線後,透過 NetworkStream(網路串流)傳輸資料;
網路僅能傳輸位元組陣列 byte[],文字必須先編碼為位元組,接收後再解碼還原成字串。
傳輸不限於文字,檔案、圖片同樣可轉換為位元組陣列進行傳送,本節先實作文字聊天功能。
關鍵 API 說明
- 伺服器端
listener.AcceptTcpClient()
- 封鎖方法(中斷等待):程式執行至此時執行緒暫停,直到用戶端發起連線;
- 回傳
TcpClient物件,代表該條用戶端連線; - 透過
tcpClient.GetStream()取得網路串流。
- 網路串流讀寫
stream.Write(位元組陣列,起始位置,長度):傳送資料stream.Read(快取陣列,起始位置,最大讀取長度):接收資料,回傳實際讀取到的位元組長度
- 編碼注意事項
課程範例使用Encoding.Unicode(UTF‑16),傳送與接收兩端編碼必須一致,否則會出現亂碼。
伺服器端 WinForms
控制項:textBoxIP、textBoxPort、textBoxInfo(訊息顯示方塊)
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace TcpServer
{
public partial class Form1 : Form
{
IPAddress ip;
TcpListener listener;
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
ip = IPAddress.Parse(textBoxIP.Text);
listener = new TcpListener(ip, Convert.ToInt32(textBoxPort.Text));
listener.Start();
textBoxInfo.Text = $"服务器启动-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
// 阻塞!主线程卡住
tcpClient = listener.AcceptTcpClient();
textBoxInfo.Text = $"连接成功-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = new byte[1024];
// 阻塞等待客户端发送消息
int length = stream.Read(byteArray, 0, 1024);
string receiveMessage = Encoding.Unicode.GetString(byteArray, 0, length);
textBoxInfo.Text = $"接收到:{receiveMessage}-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
}
}
}Code language: PHP (php)
用戶端 WinForms
控制項:textBoxIP、textBoxPort、textBoxInfo、textBoxInput(輸入方塊)buttonStart【連線】、buttonSend【傳送】
using System;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace TcpClientChat
{
public partial class Form1 : Form
{
TcpClient tcpClient;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
tcpClient = new TcpClient();
try
{
tcpClient.Connect(textBoxIP.Text, Convert.ToInt32(textBoxPort.Text));
textBoxInfo.AppendText("连接成功!\r\n");
}
catch (Exception ex)
{
MessageBox.Show("连接失败-" + ex.Message);
}
}
private void buttonSend_Click(object sender, EventArgs e)
{
string message = textBoxInput.Text;
textBoxInfo.Text = $"发送“{message}”-{DateTime.Now.ToShortTimeString()}\r\n" + textBoxInfo.Text;
NetworkStream stream = tcpClient.GetStream();
byte[] byteArray = Encoding.Unicode.GetBytes(message);
stream.Write(byteArray, 0, byteArray.Length);
}
}
}Code language: PHP (php)
以上程式碼實現用戶端與伺服器之間的訊息傳送。
用戶端與伺服器通訊
Previous: 用戶端TcpClient