艾伟_转载:用C#实现基于TCP协议的网络通讯

简介:   TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程。然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实现不是一天两天的功夫,所幸的是在.net framework环境下,我们不必要去追究TCP协议底层的实现,一样可以很方便的编写出基于TCP协议进行网络通讯的程序。

  TCP协议是一个基本的网络协议,基本上所有的网络服务都是基于TCP协议的,如HTTP,FTP等等,所以要了解网络编程就必须了解基于TCP协议的编程。然而TCP协议是一个庞杂的体系,要彻底的弄清楚它的实现不是一天两天的功夫,所幸的是在.net framework环境下,我们不必要去追究TCP协议底层的实现,一样可以很方便的编写出基于TCP协议进行网络通讯的程序。 

  要进行基于TCP协议的网络通讯,首先必须建立同远程主机的连接,连接地址通常包括两部分——主机名和端口,如www.yesky.com:80中,www.yesky.com就是主机名,80指主机的80端口,当然,主机名也可以用IP地址代替。当连接建立之后,就可以使用这个连接去发送和接收数据包,TCP协议的作用就是保证这些数据包能到达终点并且能按照正确的顺序组装起来。 

  在.net framework的类库(Class Library)中,提供了两个用于TCP网络通讯的类,分别是TcpClient和TcpListener。由其英文意义显而易见,TcpClient类是基于TCP协议的客户端类,而TcpListener是服务器端,监听(Listen)客户端传来的连接请求。TcpClient类通过TCP协议与服务器进行通讯并获取信息,它的内部封装了一个Socket类的实例,这个Socket对象被用来使用TCP协议向服务器请求和获取数据。因为与远程主机的交互是以数据流的形式出现的,所以传输的数据可以使用.net framework中流处理技术读写。在我们下边的例子中,你可以看到使用NetworkStream类操作数据流的方法。 

  在下面的例子中,我们将建立一个时间服务器,包括服务器端程序和客户端程序。服务器端监听客户端的连接请求,建立连接以后向客户端发送当前的系统时间。
  先运行服务器端程序,下面截图显示了服务器端程序运行的状况:
  然后运行客户端程序,客户端首先发送连接请求到服务器端,服务器端回应后发送当前时间到客户端,这是客户端程序的截图:
  发送完成后,服务器端继续等待下一次连接:
  通过这个例子我们可以了解TcpClient类的基本用法,要使用这个类,必须使用System.Net.Socket命名空间,本例用到的三个命名空间如下: 

  using System; 
using System.Net.Sockets;
using System.Text;//从字节数组中获取字符串时使用该命名空间中的类

  首先讨论一下客户端程序,开始我们必须初始化一个TcpClient类的实例:

  TcpClient client = new TcpClient(hostName, portNum); 

  然后使用TcpClient类的GetStream()方法获取数据流,并且用它初始化一个NetworkStream类的实例:

  NetworkStream ns = client.GetStream(); 

  注意,当使用主机名和端口号初始化TcpClient类的实例时,直到跟服务器建立了连接,这个实例才算真正建立,程序才能往下执行。如果因为网络不通,服务器不存在,服务器端口未开放等等原因而不能连接,程序将抛出异常并且中断执行。
  建立数据流之后,我们可以使用NetworkStream类的Read()方法从流中读取数据,使用Write()方法向流中写入数据。读取数据时,首先应该建立一个缓冲区,具体的说,就是建立一个byte型的数组用来存放从流中读取的数据。Read()方法的原型描述如下:

  public override int Read(in byte[] buffer,int offset,int size)

  buffer是缓冲数组,offset是数据(字节流)在缓冲数组中存放的开始位置,size是读取的字节数目,返回值是读取的字节数。在本例中,简单地使用该方法来读取服务器反馈的信息: 

  byte[] bytes = new byte[1024];//建立缓冲区 
int bytesRead = ns.Read(bytes, 0, bytes.Length);//读取字节流

  然后显示到屏幕上: 

  Console.WriteLine(Encoding.ASCII.GetString(bytes,0,bytesRead)); 

  最后不要忘记关闭连接: 

  client.Close(); 

  下面是本例完整的程序清单:

  using System; 
using System.Net.Sockets;
using System.Text;
namespace TcpClientExample
{
  public class TcpTimeClient
  {
  private const int portNum = 13;//服务器端口,可以随意修改
  private const string hostName = "127.0.0.1";//服务器地址,127.0.0.1指本机
  [STAThread]
  
static void Main(string[] args)
    {
  
  try
       {
       Console.Write(
"Try to connect to "+hostName+":"+portNum.ToString()+"\r\n");
        TcpClient client
= new TcpClient(hostName, portNum);
        NetworkStream ns
= client.GetStream();
        
byte[] bytes = new byte[1024];
        
int bytesRead = ns.Read(bytes, 0, bytes.Length);
        Console.WriteLine(Encoding.ASCII.GetString(bytes,
0,bytesRead));
        client.Close();
        Console.ReadLine();
        
//由于是控制台程序,故为了清楚的看到结果,可以加上这句
       }
      catch (Exception e)
      {
        Console.WriteLine(e.ToString());
      }
   }
  }
}

  上面这个例子清晰地演示了客户端程序的编写要点,下面我们讨论一下如何建立服务器程序。这个例子将使用TcpListener类,在13号端口监听,一旦有客户端连接,将立即向客户端发送当前服务器的时间信息。 

  TcpListener的关键在于AcceptTcpClient()方法,该方法将检测端口是否有未处理的连接请求,如果有未处理的连接请求,该方法将使服务器同客户端建立连接,并且返回一个TcpClient对象,通过这个对象的GetStream方法建立同客户端通讯的数据流。事实上,TcpListener类还提供一个更为灵活的方法AcceptSocket(),当然灵活的代价是复杂,对于比较简单的程序,AcceptTcpClient()已经足够用了。此外,TcpListener类提供Start()方法开始监听,提供Stop()方法停止监听。
  首先我们使用端口初始化一个TcpListener实例,并且开始在13端口监听: 

  private const int portNum = 13; 
TcpListener listener
= new TcpListener(portNum);
listener.Start();
//开始监听

  如果有未处理的连接请求,使用AcceptTcpClient方法进行处理,并且获取数据流: 

  TcpClient client = listener.AcceptTcpClient(); 
NetworkStream ns
= client.GetStream();

  然后,获取本机时间,并保存在字节数组中,使用NetworkStream.Write()方法写入数据流,然后客户端就可以通过Read()方法从数据流中获取这段信息:

  byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString()); 
ns.Write(byteTime,
0, byteTime.Length);
ns.Close();
//不要忘记关闭数据流和连接
client.Close();

  服务器端程序完整的程序清单如下: 

  using System; 
using System.Net.Sockets;
using System.Text;
namespace TimeServer
{
  class TimeServer
  {
    private const int portNum = 13;
    [STAThread]
    static void Main(string[] args)
    {
      
bool done = false;
      TcpListener listener
= new TcpListener(portNum);
      listener.Start();
      
while (!done)
      {
        Console.Write(
"Waiting for connection...");
        TcpClient client
= listener.AcceptTcpClient();
        Console.WriteLine(
"Connection accepted.");
        NetworkStream ns
= client.GetStream();
        
byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());
        
try
        {
          ns.Write(byteTime,
0, byteTime.Length);
          ns.Close();
          client.Close();
        }
        
catch (Exception e)
        {
          Console.WriteLine(e.ToString());
        }
      }
      listener.Stop();
    }
  }
}

  把上面两段程序分别编译运行,OK,我们已经用C#实现了基于TCP协议的网络通讯。

目录
相关文章
|
5月前
|
数据采集 算法 数据挖掘
模块化控制协议(MCP)在网络中增强智能体执行效率的研究
随着Web3技术的迅速发展,去中心化应用和智能体在各种领域的应用逐渐增多。MCP(Modularized Control Protocol,模块化控制协议)作为一种增强智能体执行能力的关键技术,为Web3场景中的智能体提供了更强的灵活性和可扩展性。本文将探讨如何利用MCP技术提升智能体在Web3场景中的执行能力,并通过实例代码展示其实现路径。
433 22
|
2月前
|
监控 负载均衡 安全
WebSocket网络编程深度实践:从协议原理到生产级应用
蒋星熠Jaxonic,技术宇宙中的星际旅人,以代码为舟、算法为帆,探索实时通信的无限可能。本文深入解析WebSocket协议原理、工程实践与架构设计,涵盖握手机制、心跳保活、集群部署、安全防护等核心内容,结合代码示例与架构图,助你构建稳定高效的实时应用,在二进制星河中谱写极客诗篇。
WebSocket网络编程深度实践:从协议原理到生产级应用
|
2月前
|
存储 机器学习/深度学习 监控
网络管理监控软件的 C# 区间树性能阈值查询算法
针对网络管理监控软件的高效区间查询需求,本文提出基于区间树的优化方案。传统线性遍历效率低,10万条数据查询超800ms,难以满足实时性要求。区间树以平衡二叉搜索树结构,结合节点最大值剪枝策略,将查询复杂度从O(N)降至O(logN+K),显著提升性能。通过C#实现,支持按指标类型分组建树、增量插入与多维度联合查询,在10万记录下查询耗时仅约2.8ms,内存占用降低35%。测试表明,该方案有效解决高负载场景下的响应延迟问题,助力管理员快速定位异常设备,提升运维效率与系统稳定性。
214 4
|
3月前
|
运维 架构师 安全
二层协议透明传输:让跨域二层协议“无感穿越”多服务商网络
简介:本文详解二层协议透明传输技术,适用于企业网工、运营商及架构师,解决LLDP/LACP/BPDU跨运营商传输难题,实现端到端协议透传,提升网络韧性与运维效率。
|
7月前
|
安全 网络协议 Linux
Linux网络应用层协议展示:HTTP与HTTPS
此外,必须注意,从HTTP迁移到HTTPS是一项重要且必要的任务,因为这不仅关乎用户信息的安全,也有利于你的网站评级和粉丝的信心。在网络世界中,信息的安全就是一切,选择HTTPS,让您的网站更加安全,使您的用户满意,也使您感到满意。
205 18
|
8月前
|
网络协议
TCP/IP与OPC协议的深度比较
总的来说,TCP/IP和OPC协议各有其优点和应用场景。TCP/IP协议是网络通信的基础,而OPC协议则是工业自动化领域的重要工具。在实际应用中,我们需要根据具体的需求和场景,选择合适的协议。
292 11
|
8月前
|
安全 网络安全 定位技术
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
253 22
|
8月前
|
网络协议 数据安全/隐私保护 网络架构
|
9月前
|
网络协议 物联网
VB6网络通信软件上位机开发,TCP网络通信,读写数据并处理,完整源码下载
本文介绍使用VB6开发网络通信上位机客户端程序,涵盖Winsock控件的引入与使用,包括连接服务端、发送数据(如通过`Winsock1.SendData`方法)及接收数据(利用`Winsock1_DataArrival`事件)。代码实现TCP网络通信,可读写并处理16进制数据,适用于自动化和工业控制领域。提供完整源码下载,适合学习VB6网络程序开发。 下载链接:[完整源码](http://xzios.cn:86/WJGL/DownLoadDetial?Id=20)
332 12
|
9月前
|
缓存 网络协议 API
掌握网络通信协议和技术:开发者指南
本文探讨了常见的网络通信协议和技术,如HTTP、SSE、GraphQL、TCP、WebSocket和Socket.IO,分析了它们的功能、优劣势及适用场景。开发者需根据应用需求选择合适的协议,以构建高效、可扩展的应用程序。同时,测试与调试工具(如Apipost)能助力开发者在不同网络环境下优化性能,提升用户体验。掌握这些协议是现代软件开发者的必备技能,对项目成功至关重要。