.net 网络编程

本文介绍TCP/IP五层模型及TCP编程方法,包括服务器与客户端的异步连接、数据收发流程,并提供.NET框架下的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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://files.cnblogs.com/bomo/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B.zip

 

转载于:https://www.cnblogs.com/hz1124/p/6086775.html

本书结合大量实例,全面介绍了基于visual c#.net网络编程,内容包括web forms、asp.net、tcp、udp端口通信、远程访问、msmq消息队列、电子邮作客户端系统、网络编程应用技巧与web services等。<br>本书所有的源代码可以通过http://www.tupwk.com.cn下载到,用户无需输入任何内容,即可使用本书中展示的所有技巧。<br>本书结构清晰,内容全面,由浅及深、注重实用,适合于初级和中级网络程序员、网络软件开发人员、网络管理员及广大计算机编程爱好者阅读。<br>第1章 net平台<br>1.1 net平台简介<br>1.1.1 什么是.net<br>1.1.2 net的功能<br>1.1.3 net的核心组件<br>1.2 net平台特点<br>1.3 net平台架构<br>1.4 本章小结<br>第2章 c#web编程基础<br>2.1 internet发展简史<br>2.1.1 www与internet<br>2.1.2 web的工作原理<br>2.1.3 超文本传输协议<br>2.2 web编程起步<br>2.2.1 html页面<br>2.2.2 html表单<br>2.2.3 静态和动态web页面<br>2.2.4 web的演化过程<br>2.3 netweb编程<br>2.3.1 aspnet<br>2.3.2 webforms<br>2.4 本章小结<br>第3章 基于asp.net网络编程<br>3.1 webforms<br>3.1.1 创建第一个web窗体<br>3.1.2 在web窗体上添加控件<br>3.1.3 将控件与数据绑定<br>3.1.4 webforms的事件响应<br>3.2 服务器端控件<br>3.3 自定义控件<br>3.3.1 创建项目<br>3.3.2 将控件添加到工具箱<br>3.3.3 个性化控件<br>3.3.4 创建自定义设计器<br>3.3.5 测试控件<br>3.4 html控件<br>3.5 aspnet应用程序<br>3.5.1 什么是应用程序<br>3.5.2 配置web.config<br>3.5.3 编写global.asax<br>3.5.4 应用和会话<br>3.5.5 安全访问控制<br>3.6 本章小结<br>第4章 基于tcp/udp协议的socket编程<br>4.1 hternet和socket简介<br>4.1.1 tcp协议简介<br>4.1.2 udp协议简介<br>4.1.3 端口简介<br>4.1.4 system.net名称空间<br>4.1.5 system.net.sockets名称空间<br>4.2 基于tcp协议的网络会话实例<br>4.2.1 服务器端编程<br>4.2.2 客户端编程<br>4.2.3 编译运行<br>4.3 基于tcp的p2p文件共享应用<br>4.3.1 qremotefilestream协议<br>4.3.2 qremotefilestreamserver类<br>4.3.3 qremotefilestreamproxy类<br>4.3.4 qfilesharingpeer类<br>4.3.5 p2p-gui程序的编写和编译运行<br>4.4 基于udp协议的网络会话实例<br>4.4.1 服务器端编程<br>4.4.2 客户端编程<br>4.4.3 编译运行<br>4.5 基于udp广播的自动收报机的实现<br>4.5.1 服务器和客户端的公共类<br>4.5.2 服务器端编程<br>4.5.3 客户端编程<br>4.5.4 编译运行<br>4.6 基于udp的客户一服务器聊天应用的实现<br>4.6.1 qtcpserversession类<br>4.6.2 qtcpserver类<br>4.6.3 聊天协议<br>4.6.4 qchatserver类<br>4.6.5 qchatclient类<br>4.6.6 编译和运行程序<br>4.7 网络资料的访问<br>4.7.1 代理的概念<br>4.7.2 访问网络资源的客户端程序<br>4.8 本章小结<br>第5章 远程访问<br>……<br>第6章 基于msmq的消息队列<br>第7章 电子邮件客户端系统<br>第8章 网络编程实用技巧示例<br>第9章 xmlwebservices编程<br>第10章 一个大整数计算的webserrices<br>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值