博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【.NET】网络编程总结
阅读量:7187 次
发布时间:2019-06-29

本文共 6500 字,大约阅读时间需要 21 分钟。

1、首先说下计算机网络中的TCP/IP参考模型

  TCP/IP把网络分为5层,每一层负责完成不同的功能

    1)应用层:传输报文,提供各种网络应用,有FTP、SMTP、HTTP等协议

    2)运输层:传输报文段,为应用程序的客户机和服务器之间提供传输应用层报文服务,协议有TCP,UDP

    3)网络层:传输数据包,协议有IP协议,选路协议

    4)链路层:传输数据帧,以太网就属于这个层

    5)物理层:在节点之间传输比特流

  应用程序是通过套接字访问网络下层的服务的,套接字是网络运输层和应用层的一个编程接口,在程序中通过套接字来进行TCP和UDP传输,运输层以下的层对程序员透明

TCP和UDP是最基本的传输协议,应用层的所有协议都是基于这两个协议进行封装扩展的

  TCP:可靠的,面向连接的连接数据传输服务,传输的是字节流,能保证数据的有序性

    1)建立连接(三次握手)  2)传输数据  3)断开连接(四次握手)

  UDP:不可靠,面向数据报的无连接的数据传输服务,传输的是是数据包,不保证数据的有序性

    广播:可以向同一个子网内的所有主机发送广播数据

    组播:可以向所有加入组网的主机发送组播数据

2、编程(本节由于篇幅太长,这里只说TCP)

  .NET 框架提供了下面几个类对实现网络通信:

    Socket:提供最基本的TCP和UDP服务

    TcpListener/TcpClient 和 UdpClient:对Socket类进行了基本封装

    NetworkStream:网络流,对网络数据的写入和读取

  使用套接字的步骤

    TCP:服务器:创建套接字 -》 绑定套接字Bind -》 监听套接字Listen -》 接受连接Accept -》 发送/接受Send/Receive -》 关闭套接字CLose

      :客户端:创建套接字 -》                     连接 -》      发送/接受Send/Receive -》 关闭套接字CLose

    UDP:创建套接字 -》 绑定套接字Bind -》  发送/接受SendTo/ReceiveFrom -》 关闭套接字CLose

  1)Socket(使用异步方式连接和收发信息,因为等待连接和等待数据的时候会让主线程阻塞)

     这里就不贴代码了,跟下面的差不多,后面下载的代码有(我用的VS2012,低版本不能查看可以直接看源文件的代码)

  2)TcpListener/TcpClient(这里也使用异步方式来连接和接收信息)

    首先创建一个异步用的数据对象

public class StateObject        {            public NetworkStream networkstream = null;            public byte[] buffer = new byte[1024];            public StateObject(NetworkStream netstream)            {                this.networkstream = netstream;            }        }

    1)服务器端(异步监听,当收到连接,则异步读取数据,注意捕获连接断开时的异常)

 

TcpListener listener;        NetworkStream networkstream;        private void btnBind_Click(object sender, EventArgs e)        {            //绑定,启动异步接受连接            try            {                int port = int.Parse(tbPort.Text);                IPAddress ipaddress = IPAddress.Parse(tbIP.Text);                IPEndPoint endpoint = new IPEndPoint(ipaddress, port);                                listener = new TcpListener(endpoint);                listener.Start(10);        //监听数位10                //开始异步接收连接请求                listener.BeginAcceptTcpClient(DoAcceptTcpClientCallback, listener);                btn.Text = "Close";            }            catch (ArgumentNullException) { }            catch (SocketException) { }        }        //异步接收请求函数        public void DoAcceptTcpClientCallback(IAsyncResult ar)        {            TcpListener listener = (TcpListener)ar.AsyncState;            try            {                TcpClient client = listener.EndAcceptTcpClient(ar);                //收到连接                this.BeginInvoke(new ThreadStart(() =>                {                    //收到连接请求,这里可以让主线程更新UI                }));                networkstream = new NetworkStream(client.Client);                StateObject so = new StateObject(networkstream);                                //开始异步读取数据                networkstream.BeginRead(so.buffer, 0, so.buffer.Length, ReadCallback, so);                //如果需要继续监听,则继续异步接收                listener.BeginAcceptTcpClient(DoAcceptTcpClientCallback, listener);            }            catch (ObjectDisposedException)            {                //Socket关闭            }        }        //异步读取数据函数        public void ReadCallback(IAsyncResult ar)        {            StateObject so = (StateObject)ar.AsyncState;            try            {                NetworkStream myNetworkStream = so.networkstream;                int length = myNetworkStream.EndRead(ar);                string receivemsg = Encoding.UTF8.GetString(so.buffer, 0, length);                this.BeginInvoke(new ThreadStart(() =>                {                    //收到数据,在这里可以让主线程更新UI                }));                so.buffer = new byte[1024];                //继续接收数据                myNetworkStream.BeginRead(so.buffer, 0, so.buffer.Length, ReadCallback, so);            }            catch (IOException)            {                this.BeginInvoke(new ThreadStart(() =>                {                    //连接断开                }));                networkstream = null;            }        }

 

    这样,服务器端就完成了监听

  2)客户端(同样通过异步实现)

TcpClient client;        NetworkStream networkstream;        private void btnConnect_Click(object sender, EventArgs e)        {            int port = int.Parse(tbPort.Text);            IPAddress ipaddress = IPAddress.Parse(tbIP.Text);            IPEndPoint endpoint = new IPEndPoint(ipaddress, port);            if (client == null)            {                //开始异步连接                client = new TcpClient();                client.BeginConnect(ipaddress, port, ConnectCallback, client);            }        }        private void ConnectCallback(IAsyncResult ar)        {            TcpClient t = ar.AsyncState as TcpClient;            try            {                t.EndConnect(ar);                networkstream = t.GetStream();                this.BeginInvoke(new ThreadStart(() =>                {                          //连接成功                                }));                //开始异步接受数据                StateObject so = new StateObject(networkstream);                networkstream.BeginRead(so.buffer, 0, so.buffer.Length, ReadCallback, so);            }            catch (SocketException)            {                 this.BeginInvoke(new ThreadStart(() =>                 {                    //连接失败,让UI更新                }));            }        }        public void ReadCallback(IAsyncResult ar)        {            StateObject so = (StateObject)ar.AsyncState;            try            {                NetworkStream myNetworkStream = so.networkstream;                int length = myNetworkStream.EndRead(ar);                string receivemsg = Encoding.UTF8.GetString(so.buffer, 0, length);                this.BeginInvoke(new ThreadStart(() =>                {                    //更新UI                }));                //继续异步接受数据                so.buffer = new byte[1024];                myNetworkStream.BeginRead(so.buffer, 0, so.buffer.Length, ReadCallback, so);            }            catch (IOException)            {                this.BeginInvoke(new ThreadStart(() =>                {                    //连接断开                }));                networkstream = null;            }        }

  3)接下来是发送数据

private void btnSend_Click(object sender, EventArgs e)        {            if (networkstream != null)            {                byte[] sendbyte = System.Text.Encoding.UTF8.GetBytes("你好:)");                networkstream.Write(sendbyte, 0, sendbyte.Length);            }            else            {                tbMsg.AppendText("未连接\n");            }        }

  具体项目代码  

 

 

 

转载地址:http://gwjkm.baihongyu.com/

你可能感兴趣的文章
[转]SSIS包的调用方式
查看>>
使用jQuery.form插件,实现完美的表单异步提交
查看>>
auto make System.map to C header file
查看>>
【转】Android中自定义控件的步骤
查看>>
Eclipse中web项目部署至Tomcat步骤
查看>>
00-Java 语言简介
查看>>
转:体验Java SE 6 中的 GroupLayout
查看>>
SharePoint: Creating a custom field
查看>>
select中case-when-then用法
查看>>
13、结构体常量 Struct Literals
查看>>
VC++引用类型与指针类型
查看>>
PHP - Ubuntu下ZendFramework环境的搭建
查看>>
Ext.form.Label标签字段
查看>>
Winwdos Phone 从手机中读取相册图片
查看>>
SSIS 包配置的过程
查看>>
【转】C++的const_cast的问题
查看>>
最快最简单的排序——桶排序
查看>>
mysql之触发器trigger
查看>>
Spring单例Bean和线程安全
查看>>
[Angular 2] Using Array ...spread to enforce Pipe immutability
查看>>