網絡應用程序的兩種設計模式git
B/S(Broswer/Server)瀏覽器/服務器windows
C/S(clinet/Server)客戶端/服務器設計模式
引用命名空間:瀏覽器
using sytem.net;緩存
using system.net.sockets;服務器
using system.io;網絡
1 、通訊流程socket
服務器tcp
a、 //設置 ip(所要監聽和創建鏈接的IP ) Port //端口
IPP = new IPEndPoint(IPAddress.Any,65535);編輯器
b、
//設置 socket IP類型(IPV4(默認) ,IPV6) sokettype 流和包 此爲流 協議類型 Tcp/UDP ICMP 等
socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
c //綁定IP 和Port
socket.Bind(IPP);
//監聽鏈接
d socket.Listen(0);
e 消息處理髮送和接收
開啓消息監聽線程
th th=new th(Receiver);
public void Receiver(){
//注意 若是是在UI程序 必須處理線程互斥問題
lock(this)
{
//發生互斥的資源
}
}
消息發送
public void Sender(){
}
f 通訊結束
關閉掉 IO 流 終止線程 關閉全部socket活動
TAcceptMsg.Abort();
socket.Close();
客戶端
a 配置要鏈接的IP和端口(和服務器的端口同樣)
IPP = new IPEndPoint(IPAddress.Parse(txt_addr.Text),int.Parse(txt_port.Text));
b //配置socket
socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//鏈接
c socket.Connect(IPP);
d 消息處理
開啓消息監聽線程
th th=new th(Receiver);
public void Receiver(){
//注意 若是是在UI程序 必須處理線程互斥問題
lock(this)
{
//發生互斥的資源
}
}
消息發送
public void Sender(){
}
e 通訊結束
關閉掉 IO 流 終止線程 關閉全部socket活動
TAcceptMsg.Abort();
socket.Close();
二、經常使用類與其屬性方法
3 、常見通訊方式
4 、 案例
客戶端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Threading;
using System.Net.Sockets;
namespace WinFrm_TcpClient
{
public partial class MainFrm : Form
{
public MainFrm()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
//鏈接狀態
public bool bConnectd = false;
//監聽線程
public Thread TAcceptMsg = null;
//用於通訊的Ip和Port
public IPEndPoint IPP = null;
//SOcket 通訊
public Socket socket = null;
//網絡數據流
public NetworkStream nStream=null;
//讀取器
public TextReader tReader = null;
//編輯器
public TextWriter tWriter = null;
//消息監聽發送
public void AcceptMessage() {
string tmp;
while (bConnectd)
{
try
{
tmp = tReader.ReadLine();
if (tmp.Length != 0)
{
lock (this)
{
rich_MessagDialog.AppendText("服務器"+tmp+"\n");
}
}
}
catch {
MessageBox.Show("沒法鏈接服務器");
}
try
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch { }
}
}
private void btn_connect_Click(object sender, EventArgs e)
{
try
{
IPP = new IPEndPoint(IPAddress.Parse(txt_addr.Text),int.Parse(txt_port.Text));
//配置socket
socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//鏈接
socket.Connect(IPP);
if (socket.Connected)
{
nStream = new NetworkStream(socket);
tReader = new StreamReader(nStream);
tWriter = new StreamWriter(nStream);
TAcceptMsg = new Thread(AcceptMessage);
bConnectd = true;
TAcceptMsg.Start();
}
}
catch {
MessageBox.Show("沒法鏈接到服務器");
}
}
private void btn_Send_Click(object sender, EventArgs e)
{
if (bConnectd)
{
try
{
lock (this)
rich_MessagDialog.AppendText("客戶端" + rich_Sengmsg.Text + "/n");
tWriter.WriteLine(rich_Sengmsg.Text);
tWriter.Flush();
rich_Sengmsg.Text = "";
}
catch
{
MessageBox.Show("語與服務器斷開");
}
}
else
{
MessageBox.Show("未鏈接服務器,不能通訊");
}
}
private void MainFrm_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
TAcceptMsg.Abort();
socket.Close();
}
catch { }
}
}
}
服務器
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace WinFrm_TcpServer
{
public partial class MainFrm : Form
{
public MainFrm()
{
InitializeComponent();
//取消線程異常
CheckForIllegalCrossThreadCalls = false;
}
//服務器鏈接狀態
private bool bConnected=false;
//監聽消息線程
private Thread tAcceptMsg = null;
//用於socket通訊串口 的 IP 和 Port
private IPEndPoint IPP = null;
//Socket通訊
private Socket socket = null;
//socket客戶端
private Socket clientsocket = null;
//網絡訪問數據流
private NetworkStream nStream = null;
//消息讀取器
private TextReader tReader = null;
//編寫器
private TextWriter tWriter = null;
//顯示消息
public void AcceptMessag()
{
//阻塞鏈接來自客戶端
clientsocket = socket.Accept();
if (clientsocket != null)
{
bConnected = true;
lab_state.Text = "客戶端鏈接"+
clientsocket.RemoteEndPoint.ToString() + "成功創建鏈接";
}
//從客戶獲取網絡數據流
nStream=new NetworkStream(clientsocket);
//讀取字節流
tReader = new StreamReader(nStream);
//寫字節流
tWriter = new StreamWriter(nStream);
string tmp;//臨時消息緩存
while (bConnected)
{
//捕獲錯誤
try
{
tmp = tReader.ReadLine();
if (tmp.Length != 0)
{
//線程互斥處理
lock (this)
{
rich_MessageDialog.AppendText( "客戶端:"+tmp+"\n");
}
}
}
catch
{
tAcceptMsg.Abort();
MessageBox.Show("沒法鏈接到客戶端!!");
}
try
{
//關閉消息發送
clientsocket.Shutdown(SocketShutdown.Both);
//關閉socket 釋放全部資源
clientsocket.Close();
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch { }
}
}
private void btn_startServer_Click(object sender, EventArgs e)
{
//全部ip 和 Port 65535
IPP = new IPEndPoint(IPAddress.Any,65535);
//設置 socket IP類型(IPV4(默認) ,IPV6) sokettype 流和包 此爲流 協議類型 Tcp/UDP ICMP 等
socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//綁定IP 和Port
socket.Bind(IPP);
//監聽鏈接
socket.Listen(0);
//開啓監聽消息線程
tAcceptMsg = new Thread(AcceptMessag);
tAcceptMsg.Start();
btn_startServer.Enabled = false;
}
private void btn_Send_Click(object sender, EventArgs e)
{
//檢測是否有文本
if (rich_Sendmsg.Text.Length != 0)
{
if (bConnected)
{
try {
//線程互斥處理
lock (this)
{
rich_MessageDialog.AppendText("服務器"+rich_Sendmsg.Text+"\n");
//寫入消息
tWriter.WriteLine(rich_Sendmsg.Text);
//刷新緩衝
tWriter.Flush();
rich_Sendmsg.Text = "";
}
}
catch {
MessageBox.Show("斷開鏈接沒法與客戶端通訊");
}
}
}
else {
MessageBox.Show("請輸入消息");
}
}
private void MainFrm_FormClosing(object sender, FormClosingEventArgs e)
{
try {
socket.Close();
tAcceptMsg.Abort();
}
catch {
}
}
}
}
運行環境 : windows 7
開發環境:Microsoft Visual Studio 2010
源碼地址 :https://gitee.com/codemaner/windowscshare_review/tree/master
資源名稱 winFrm_tcpclient winFrm_tcpServer