本站业务范围:1、PC端软件开发、网站开发 2、移动端APP、网站、微信接口、微商城开发 3、视频教程、课程设计和辅导 4、单片机开发 5、串口通讯调试
 当前位置:文章中心 >> NodeJs视频教程
立即购买视频教程 C#中的TCP网络编程
夜鹰教程网 来源:www.yyjcw.com 日期:2017-11-4 16:43:13
本文针对有C#的初学者而写的,主要讲解如何利用C#进行网络编程。如果你已经有一些网络编程的经验(只需要懂得网络编程的基本常识即可),并且理解C#的基本语法,那么这篇文章可以很快地带你进入C#网络编程的世界。如果你的基础不好,也不要紧,我相信这篇文章也会有你需要的内容。

这篇文章不能解决你的问题?我们还有相关视频教程云课堂 全套前端开发工程师培训课程

微信号:yyjcw10000 QQ:1416759661  远程协助需要加QQ!

业务范围:视频教程|程序开发|在线解答|Demo制作|远程调试| 点击查看相关的视频教程

技术范围:全端开发/前端开发/webapp/web服务/接口开发/单片机/C#/java/node/sql server/mysql/mongodb/android/。 





 网络编程基础复习:
图1. TCP编程基本模型

 
1.gif 

        相信很多人看到图1应该不会陌生,这是一个利用TCP进行通信的经典模型图。我想大家都应该把这张图记在心中。在此我就不讲述上图中每个API的意思了,百度一下,你就知道。我想说的是,难道你不觉得这么编程很累吗? 我们需要去调用每个API函数,然后每个判断返回值是多少,如果你忘记了哪个API的参数形式还得去查MSDN,这种时间花费是巨大的,尤其当你做应用层的快速开发时。

 
 2.jpg
        图2是利用UDP通信时的编程基本模型,这个模型较为简单,但是应用极为广泛,相比TCP而言,我本人觉得利用UDP通信是一门更为高深的技术,因为它是无连接的,换言之,它的效率与灵活度就更高些。

 
图2. UDP编程基本模型

 

        在此我补充一点,关于何时利用TCP通信、何时利用UDP通信的问题。他们的特性其实已经决定了他们的适用范围。在进行大数据量、持续连接时,我们使用TCP,例如FTP协议;而在进行小规模数据、突发性高的通信时,我们使用UDP,例如聊天程序。但是,这并不是绝对的事情。例如流媒体通信,它是大数量、持续的通信,但是使用的是UDP协议,为什么呢?——因为我们不关心丢失的帧,人的肉眼是无法识别出少量的帧丢失的。那么使用UDP通信就可以大幅度提高效率,降低网络负载。

 

 

C#之TCP编程

 

    如何创建一个套接字?

 

    我们先来看看利用Winsock2是如何建立一个套接字的:

    首先,我们要加载套接字库,然后再建立套接字。大致代码如下:

     

    WORD wVersion=MAKEWORD(2,2);  
    WSADATA wsaData;  
    if(WSAStartup(wVersion,&wsaData))  
    {  
    WSACleanup();  
    returnFALSE;  
    }  
       
    m_sock=WSASocket(AF_INET,SOCK_DGRAM,IPPROTO_UDP,NULL,0,0);  
    if(m_sock==INVALID_SOCKET)  
    {  
            MessageBox("创建套接字失败!");  
            return FALSE;  
    }  

     

            难道你不觉得利用Winsock2创建一个套接字很费劲吗?如果你在Linux环境中变成倒是可以省掉加载套接字的部分,但是却只能反复的调用API,这样也是很费时的事情。那我们再看看看利用C#是如何帮你简化工作的。这里我会介绍TCPClient类。

            以上是从MSDN上截取的一段话,可见我们利用TCPClient还处理与TCP通信相关的操作。TCPClient有四个构造函数,每个构造函数的用法是有不同的。这里我补充一个知识,那就是端地址在C#中描述。我们知道,我们用一个IP地址和一个端口号就可以表示一个端地址。在C#中我们利用IPEndPoint类来表示一个端地址,本人经常利用如下的构造函数来创建一个IPEndPoint类。

     

        IPEndPoint localEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"),6666);  

     

         
        这样来表示一个端地址是不是比创建一个struct sockaddr_in的结构体来的快呢?

         

 

 

    如何绑定一个端地址?

 

           我们已经创建了一个端地址,也构造了套接字(TCPClient类),那么如何将二者绑定起来呢?也许你已经发现了,在建立TCPClient的时候我们其实就可以绑定端地址了。如果你使用的TCPClient tcp_Client=new TCPClient()的构造函数来创建的TCPClient,那么系统会认为你没有人为的制定端地址,而会自动帮你制定端地址,在创建客户端的TCPClient时我们常常这样做,因为我们不关心客户端的端地址。如果是服务器监听呢?在服务器监听时我们会使用例外一个类,叫做TCPListener,接下来我会讲到。我们可以利用TCPClient(IPEndPoint)来构造一个绑定到固定端地址的TCPClient类。例如:

     

        TcpClient tcp_Client = new TcpClient(localEP);  

     

 

    如何监听套接字?

 

           到现在为此我们还没讨论如何监听一个套接字。在传统的socket编程中,我们创建一个套接字,然后把它绑定到一个端地址,而后调用Listen()来监听套接字。而在C#中,我们利用TCPListener来帮我们完成这些工作。让我们先来看看如何在C#监听套接字。

        IPEndPointlocalEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"),6666);  
        TcpListenerListener = new TcpListener(localEP);  
        Listener.Start(10);  

 

            我们首先创建需要绑定的端地址,而后创建监听类,并利用其构造函数将其绑定到端地址,然后调用Start(int number)方法来真正实施监听。这与我们传统的socket编程不同。以前我们都是先创建一个socket,然后再创建一个sockaddr_in的结构体。我想你应该开始感受到了C#的优势了,它帮我们省去了很多低级、繁琐的工作,让我们能够真正专注于我们的软件架构和设计思想。

 

    如何接受客户端连接?

 

    接听套接字后面自然就是接受TCP连接了。我们利用下面一句话来完成此工作:

         

            TcpClient remoteClient =Listener.AcceptTcpClient();  

         

            类似于accept函数来返回一个socket,利用TCPListener类的AcceptTcpClient方法我们可以得到一个与客户端建立了连接的TCPClient类,而由TCPClient类来处理以后与客户端的通信工作。我想你应该开始理解为什么会存在TCPClient和TCPListener两个类了。这两个类的存在有着更加明细的区分,让监听和后续的通信真正分开,让程序员也更加容易理解和使用了。

 

        这里我还得补充一点:监听是一个非阻塞的操作(Listener.Start()),而接受连接是一个阻塞操作(Listener.AcceptTcpClient)。

 

 

        说了这么多,还不如来个实例来的明确。接下来,我会通过一个简单的控制台聊天程序来如何使用这些。先贴代码吧!

服务器端:

 

    <span style="font-family:'Microsoft YaHei';font-size:18px;">using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.Net;  
    using System.Net.Sockets;  
       
    namespace Demo  
    {  
        class Program  
        {  
            static void Main(string[]args)  
            {  
                byte[]SendBuf = Encoding.UTF8.GetBytes("Hello,Client!");    //发给客户端的消息;  
                IPEndPointlocalEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"),6666);        //本地端地址  
                TcpListenerListener = new TcpListener(localEP);            //建立监听类,并绑定到指定的端地址  
                Listener.Start(10);           //开始监听                                                              
                Console.WriteLine("Server is listening...");                             
                TcpClientremoteClient = Listener.AcceptTcpClient();  //等待连接(阻塞)  
                Console.WriteLine("Client:{0} connected!",remoteClient.Client.RemoteEndPoint.ToString()) ;     //打印客户端连接信息;  
                remoteClient.Client.Send(SendBuf);     //发送欢迎信息;  
                remoteClient.Close();                  //关闭连接;  
            }  
        }  
    }</span>  


 

 

客户端:

 

      

 

    <span style="font-family:'Microsoft YaHei';font-size:18px;">using System;  
    using System.Collections.Generic;  
    using System.Linq;  
    using System.Text;  
    using System.Net;  
    using System.Net.Sockets;  
      
    namespace Demo_Client  
    {  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                byte[] RecvBuf=new byte[1024];                    //申请接收缓存;  
                int RecvBytes = 0;                                            //接收字节数;  
                string recvmsg=null;                                      //接收消息;  
      
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6666);      //远程服务器端地址;  
                TcpClient remoteServer = new TcpClient();                   //创建TCPClient类来与服务器通信;  
                remoteServer.Connect(remoteEP);                                  //调用connect方法连接远端服务器;  
                Console.WriteLine("I'm using {0}.", remoteServer.Client.LocalEndPoint);          //打印自己使用的端地址;  
                RecvBytes=remoteServer.Client.Receive(RecvBuf);                           //接受服务器发送过来的消息;  
                recvmsg=Encoding.UTF8.GetString(RecvBuf,0,RecvBytes);          //将接受到的字节码转化为string类型;  
                Console.WriteLine("Server says:{0}.", recvmsg);              //打印欢迎信息;  
            }  
        }  
    }</span>  


 

 

          在C#网络编程中,我们要用到两个名空间,分别是System.Net和System.Net.Socket。可能有人会有这样的疑惑,干嘛要申请一个Byte数组。我们知道,在传统socket编程中,我们都是用char*来发送或者接受消息的,其实char*和Byte[]是同源的。他们都是一个Byte,而使用Byte[]能更易于人们理解和转化为其他类型。我们知道网络间传输的字节流,而Byte[]刚好符合了这个思想。如果对以上类的用法不理解或者不熟悉的话,建议查看MSDN,上面讲解的很详细。

     

    现在看看运行效果:

 3.jpg
图3 运行效果(左为服务器,右为客户端)

 

           好啦,到这里我们C#网络编程初步之TCP基本上算告一段落了,我只讲解了最为基础的部分,仅做抛砖引玉的作用。每个类的使用千变万化,希望你能找到最适合自己使用方法。现在你可以对比以前类似程序的代码了,看看我前面有没有说错。而且,越到后来你会越来越体会到C#人性化的一面。

     

          后期的博文中,我会更新C#网络编程初步之UDP.本人更喜欢利用UDP来进行通信,至于为什么我已经说过了。以后,我会逐步写一些网络编程的高级内容,例如异步通信、多线程编程,并关注程序员经常遇到的一些棘手问题,比如TCP边界的确定等等。有机会,我也会同大家讨论网络编程中常用的软件设计思想与架构。

复制链接 网友评论 收藏本文 关闭此页
上一条: C#如何设置KeepAlive  下一条: HTTP协议的详解
夜鹰教程网成立于2008年,目前已经运营了将近 13 年,发布了大量关于 html5/css3/C#/asp.net/java/python/nodejs/mongodb/sql server/android/javascript/mysql/mvc/easyui/vue/echarts原创教程。 我们一直都在坚持的是:认证负责、一丝不苟、以工匠的精神来打磨每一套教程,让读者感受到作者的用心。我们默默投入的时间,确保每一套教程都是一件作品,而不是呆板的文字和视频! 目前我们推出在线辅导班试运营,模式为一对一辅导,教学工具为QQ。我们的辅导学科包括 java 、android原生开发、webapp开发、商城开发、C#和asp.net开发,winform和物联网开发、web前端开发,但不仅限于此。 普通班针对的是国内学员,例如想打好基础的大学生、想转行的有志青年、想深入学习的程序员、想开发软件的初学者或者业余爱好者等。 就业办针对即将毕业上岗的大四学生,或者打算转行的初级开发工程师。 留学生班针对的是在欧美、加拿大、澳洲、日本、韩国、新加坡等地留学的中国学子,目的是让大家熟练地掌握编程技能,按时完成老师布置的作业,并能顺利地通过考试。 详细咨询QQ:1416759661   夜鹰教程网  基于角色的权限管理系统(c-s/b-s)。
  夜鹰教程网  基于nodejs的聊天室开发视频教程
  夜鹰教程网  Git分布式版本管理视频教程
  夜鹰教程网  MVC+EasyUI视频教程
  夜鹰教程网  在线考试系统视频教程
  夜鹰教程网  MongoDB视频教程。
  夜鹰教程网 Canvas视频教程
  夜鹰教程网 报表开发视频教程
  推荐教程/优惠活动

  热门服务/教程目录

  夜鹰教程网  新手必看,详细又全面。
  夜鹰教程网  购买教程  夜鹰教程网  在线支付-方便
  夜鹰教程网  担保交易-快捷安全   夜鹰教程网  闪电发货
  夜鹰教程网  电话和QQ随时可以联系我们。
  夜鹰教程网 不会的功能都可以找我们,按工作量收费。

客服电话:153 9760 0032

购买教程QQ:1416759661  
  热点推荐
在Windows系统下搭建SVN服务器
宽带连接速度慢
在iis下设置伪静态的规则和方法
Oralce 9i安装OID目录服务器说明
需要停止的windows 2003 server服…
.htaccess文件设置技巧16则
Apache SSL证书安装指南
linux下手工修改分区后的挂载
MSN服务器为什么不放置在中国境内…
自定义MIME类型 网络空间支持FLV
稳定的国外网站服务器对SEO排名没…
Windows下定期自动备份网站软件—…
实战讲解:从零开始配置Linux服务器…
IIS错误代码及其含义
服务器领域众“菜鸟”们的几个常见…
  尊贵服务
夜鹰教程网 承接业务:软件开发 网站开发 网页设计 .Net+C#+VS2008+MSsql+Jquery+ExtJs全套高清完整版视频教程
  最近更新
nodejs文件上传代码
nodejs如何设置允许跨域请求
npm 项目更换目录后无法启动
Git常用命令学习
Node.js 连接 MongoDB
Node.js JXcore 打包
Node.js 多进程详解
Node.js RESTful API
Node.js Express 框架 文件上传等…
Node.js Web 模块
Node.js 工具模块
Node.js GET/POST请求
Node.js 文件系统
Node.js 常用工具函数
Node.js 全局对象
  工具下载  需要远程协助? 

sql2008视频教程 c#视频教程

VIP服务:如果您的某个功能不会做,可以加我们QQ,给你做DEMO!

JQUERY  Asp.net教程

MVC视频教程  vs2012
.NET+sql开发
手机:15397600032 C#视频教程下载
微信小程序 vue.js高级实例视频教程

教程咨询QQ:1416759661


这篇文章不能解决你的问题?我们还有相关视频教程云课堂 全套前端开发工程师培训课程

微信号:yyjcw10000 QQ:1416759661  远程协助需要加QQ!

业务范围:视频教程|程序开发|在线解答|Demo制作|远程调试| 点击查看相关的视频教程

技术范围:全端开发/前端开发/webapp/web服务/接口开发/单片机/C#/java/node/sql server/mysql/mongodb/android/。 



关于我们 | 购买教程 | 网站建设 | 技术辅导 | 常见问题 | 联系我们 | 友情链接

夜鹰教程网 版权所有 www.yyjcw.com All rights reserved 备案号:蜀ICP备08011740号3