网络应用程序的两种设计模式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