C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨

C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨

简介

本文主要介绍使用C#进行Socket网络编程时,涉及到的TCP/IP协议中的各个层次模型、端口以及报文等内容,并提供两个基本示例进行说明。

TCP/IP协议层次模型

TCP/IP协议是网络通信的基础,它将网络通信分为许多层,每一层负责不同的任务。这些层从下往上分别是:物理层、数据链路层、网络层、传输层、应用层。

下面是这些层级及其任务的简单描述:

  • 物理层:定义网络的物理布局以及底层数据传输,如电流、电压等。

  • 数据链路层:负责在物理层上,根据MAC地址,完成节点之间的通信;将从网络层接收到的IP数据报组成帧,在物理层上传输。

  • 网络层:为数据通信提供路由、寻址、分包等服务,负责网间的数据传输,通过IP地址来唯一标识不同的设备。

  • 传输层:为上层协议提供可靠的端到端通信,并提供差错检测和重传等机制,常用的协议有TCP和UDP。

  • 应用层:我们编写的程序所用的协议,如HTTP、FTP、SMTP等。

Socket端口

在TCP/IP协议中,每个设备都有一个IP地址,但这个地址只是标识了设备,而没有标识一个应用程序。为了实现设备与设备之间的通信,需要一个能够分辨应用程序的标识,这个标识就是端口。

端口是一个16位的整数,范围从0到65535,其中0到1023是被保留的,一般作为著名的端口使用,如HTTP协议的80端口、FTP协议的21端口等;1024到65535是动态端口,由操作系统分配给应用程序使用。

Socket报文

Socket报文是进行网络通信时所传输的数据单元,可以理解为一段二进制数据流。在TCP/IP协议中,Socket报文主要有三部分组成:

  • IP头部:包含了发送方和接收方的IP地址,IP协议版本,以及一些与IP协议相关的控制字段。

  • TCP头部:包含了TCP协议的各种控制字段,如端口号、序列号和确认号等。

  • 数据段:将应用程序的数据流发送给TCP层,并分段传输。

示例一:Socket服务端及其客户端

下面是一个简单的Socket服务端和客户端程序实例,适用于 TCP/IP 协议:

  1. 服务端:
using System;  
using System.Net;  
using System.Net.Sockets;  
using System.Text;

class Program  
{  
    static void Main(string[] args)  
    {  
      try  
      {  
            IPAddress ipAd = IPAddress.Parse("127.0.0.1");  
            TcpListener myList=new TcpListener(ipAd, 8001);  

            myList.Start();  
            Console.WriteLine("等待客户端连接......");  

            while(true)  
            {  
                TcpClient client = myList.AcceptTcpClient();  
                Console.WriteLine("客户端已连接...");  

                NetworkStream netStream = client.GetStream();  
                byte[] bytes = new byte[1024];  
                int i = netStream.Read(bytes, 0, bytes.Length);  
                string data = Encoding.ASCII.GetString(bytes, 0, i);  
                Console.WriteLine("收到客户端消息: {0}", data);  

                string response = "谢谢连接我们,再见!";  
                byte[] message = Encoding.ASCII.GetBytes(response);  
                netStream.Write(message, 0, message.Length);  
                client.Close();  
            }  
            myList.Stop();  
        }  
        catch (Exception e)  
        {  
            Console.WriteLine("出现异常: {0}", e.ToString());  
        }  
   }
}  
  1. 客户端:
using System;  
using System.Net;  
using System.Net.Sockets;  
using System.Text;  

class Program  
{  
    static void Main(string[] args)  
    {  
        try  
        {  
            TcpClient tcpclnt = new TcpClient();  
            Console.WriteLine("向服务端发送连接请求......");  
            tcpclnt.Connect("127.0.0.1", 8001);  

            byte[] bytes = Encoding.ASCII.GetBytes("客户端发送的数据......");  
            NetworkStream stream = tcpclnt.GetStream();  
            stream.Write(bytes, 0, bytes.Length);  
            Console.WriteLine("向服务端发送消息: {0}", Encoding.ASCII.GetString(bytes, 0, bytes.Length));  

            bytes = new byte[1024];  
            int i = stream.Read(bytes, 0, bytes.Length);  
            Console.WriteLine("从服务端收到消息: {0}", Encoding.ASCII.GetString(bytes, 0, i));  

            tcpclnt.Close();  
        }  
        catch (Exception e)  
        {  
            Console.WriteLine("出现异常: {0}", e.ToString());  
        }  
    }  
}  

示例二:Socket异步通信

下面的示例演示一个异步的Socket服务器,它可以同时处理多个请求。

using System;  
using System.Net;  
using System.Net.Sockets;  
using System.Text;

class Program  
{  
    static int port = 8001;  
    static TcpListener listener = new TcpListener(IPAddress.Any, port);  

    static void Main(string[] args)  
    {  
        listener.Start();  
        Console.WriteLine("等待客户端连接...");

        var state = new StateObject();  

        while(true)  
        {  
            listener.BeginAcceptTcpClient(AcceptTcpClientCallback, state);  
            Console.WriteLine("正在等待下一个客户端连接...");  
        }  
    }  

    static void AcceptTcpClientCallback(IAsyncResult ar)  
    {  
        Console.WriteLine("客户端连接成功...");  

        var state = (StateObject)ar.AsyncState;  
        TcpClient client = listener.EndAcceptTcpClient(ar);   
        state.Client = client;  

        NetworkStream stream = state.Client.GetStream();  
        byte[] buffer = new byte[1024];  
        stream.BeginRead(buffer, 0, buffer.Length, ReadCallback, state);  
    }  

    static void ReadCallback(IAsyncResult ar)  
    {    
        var state = (StateObject)ar.AsyncState;  
        NetworkStream stream = state.Client.GetStream();  
        int length = stream.EndRead(ar);  

        string data = Encoding.ASCII.GetString(state.Buffer, 0, length);  
        Console.WriteLine("收到客户端消息:{0}", data);  

        byte[] responseBytes = Encoding.ASCII.GetBytes("谢谢友善的客户端!");  
        stream.BeginWrite(responseBytes, 0, responseBytes.Length, WriteCallback, state);  
    }

    static void WriteCallback(IAsyncResult ar)  
    {  
        var state = (StateObject)ar.AsyncState;  
        NetworkStream stream = state.Client.GetStream();  
        stream.EndWrite(ar);  
        stream.BeginRead(state.Buffer, 0, state.Buffer.Length, ReadCallback, state);  
    }
}  

class StateObject  
{  
    public TcpClient Client { get; set; }  

    public byte[] Buffer = new byte[1024];  
}  

上面的代码中,异步通信主要通过BeginXXX和EndXXX方法进行,回调函数则负责对数据进行处理和响应数据。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#开发之Socket网络编程TCP/IP层次模型、端口及报文等探讨 - Python技术站

(0)
上一篇 2023年6月7日
下一篇 2023年6月7日

相关文章

  • 关于C#反射 你需要知道的

    关于C#反射的知识,以下是本文的完整攻略: 什么是C#反射 C#反射指的是在运行时动态访问和操作程序集中的类型、属性、方法等信息的能力。通过C#反射,我们可以在运行时获取程序集的元数据信息并进行操作,比如创建实例、调用方法、获取属性等,从而使代码更加灵活、具有可扩展性和适应性。 如何使用C#反射 使用C#反射需要以下步骤: 加载程序集:使用Assembly.…

    C# 2023年5月31日
    00
  • .NET 资源文件resx、Resources详细说明

    下面是关于.NET资源文件resx和Resources的详细说明: 什么是资源文件? 在.NET中,资源文件用于存储和管理应用程序或组件的非代码资源,如文本、图像、音频、视频等。它允许在应用程序运行时动态加载这些资源,在不同语言环境下提供本地化支持,并且可以在编译时和运行时通过代码访问这些资源。 .NET资源文件有两种类型:resx文件和Resources类…

    C# 2023年5月31日
    00
  • 深入浅析C# 11 对 ref 和 struct 的改进

    深入浅析C# 11对ref和struct的改进 在C# 11中,对于ref和struct这两个关键词进行了一些改进和优化,本文将对这些改进进行详细的讲解。 对于ref的改进 在C# 11中,ref的作用被扩大到了包括字段、属性、方法参数和返回值等方面。 使用ref字段 我们可以使用ref来引用一个字段,并且可以对其进行修改,如下所示: public clas…

    C# 2023年5月15日
    00
  • C# System.TypeInitializationException 异常处理方案

    首先我们来简单地了解一下什么是”System.TypeInitializationException”异常。 “System.TypeInitializationException”是.NET框架中的一种异常,它通常发生在类或结构体初始化时,当初始化过程中发生错误时就会抛出该类异常。例如,在类的静态构造函数中,初始化对象时出现错误,或者在静态变量初始化期间出…

    C# 2023年5月15日
    00
  • ASP.NET预备知识学习笔记

    当学习ASP.NET时,首先需要具备一些预备知识,包括以下内容: 1. C#编程语言基础 学习数据类型(int,float,bool,string等) 学习控制结构(if-else,for,while等) 学习面向对象概念(类,对象,继承,封装等) 学习集合类型(数组,List,Dictionary等) 2. HTML和CSS基础 学习HTML标签,了解HT…

    C# 2023年5月15日
    00
  • 详解C#编程中.NET的弱事件模式

    详解C#编程中.NET的弱事件模式 弱事件模式在C#编程中是一个非常重要的概念,它可以帮助我们在事件订阅过程中避免出现内存泄漏的问题,特别是在大型项目中应用广泛。本文将详细讲解如何在C#编程中使用.NET的弱事件模式。 什么是弱事件模式 在C#编程中,事件订阅是一种常见的模式,通过它我们可以在事件发生时调用另一个方法来处理其逻辑。但是,如果我们在事件订阅过程…

    C# 2023年6月3日
    00
  • C#多线程的相关操作讲解

    C#多线程的相关操作讲解 在 C# 中,可以通过多线程机制来使一个程序同时执行多个任务,更好地利用计算资源,提高程序的效率和性能。本篇文章将针对 C# 多线程相关操作进行详细讲解,内容包括线程的创建、启动、停止,线程同步和互斥,以及线程池等多方面。 一、线程的创建和启动 C# 中可以使用 Thread 类来创建和启动线程。Thread 构造函数有两个重载形式…

    C# 2023年5月15日
    00
  • .net core如何使用Redis发布订阅

    .NET Core中使用Redis发布订阅攻略 在 .NET Core 中,我们可以使用 Redis 发布订阅功能来实现消息传递和事件通知。本攻略将介绍如何在 .NET Core 中使用 Redis 发布订阅功能。 步骤 以下是使用 Redis 发布订阅功能的步骤: 安装 Redis。 在服务器上安装 Redis。可以使用官方网站提供的安装包或者使用包管理器…

    C# 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部