本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本项目旨在介绍如何使用C#语言开发一个简易版的即时通讯软件,模拟腾讯QQ的基本功能。项目内容包括使用Windows Forms创建用户界面、利用SQL Server数据库实现注册登录机制、网络通信原理、多线程处理、数据序列化以及安全性措施。该教程不仅提供了详细的开发流程,还深入讲解了多种编程技术的应用,帮助开发者掌握即时通讯系统开发的关键技能。

1. C#编程语言介绍

C#编程语言的起源与发展

C#(读作“看井”)是微软公司于2000年发布的一种面向对象的编程语言,属于.NET框架的一部分。它的设计理念是结合Visual Basic的易用性和C++的强大功能。C#的第一个版本随着.NET框架1.0发布,其版本迭代与.NET框架紧密相连,例如C# 7.0伴随着.NET Core 2.0的推出。C#语言不断进化,现在已经成为企业级开发、游戏开发、移动应用等众多领域的主流选择。

C#语言的特性与应用领域

C#的语言特性包括类型安全性、垃圾回收机制、异常处理、泛型编程等,它支持继承、封装、多态等面向对象的原则。这些特性使得C#在构建复杂软件系统时能够提供高度的可靠性和维护性。C#广泛应用于桌面应用、游戏开发(通过Unity引擎)、Web应用、云服务、物联网等多个领域,尤其在Windows平台上占据了重要的地位。

C#语法基础与代码结构

C#代码结构清晰,语法简洁,易于学习和使用。它包括了基础的数据类型、控制流程(如if语句、循环结构)、方法和函数定义等元素。一个典型的C#程序由命名空间、类和方法组成,类是组织代码的主要方式,而方法则是执行实际操作的单元。此外,C#支持LINQ(语言集成查询),它提供了一种强大而一致的方式,用于操作数据源。

using System;  // 引入命名空间

namespace HelloWorld // 定义命名空间
{
    class Program // 定义类
    {
        static void Main(string[] args) // 主入口方法
        {
            Console.WriteLine("Hello, World!"); // 输出语句
        }
    }
}

通过上述简单的程序示例,我们可以看到C#的基础语法结构:引入命名空间、创建程序入口点、编写输出语句。这也展示了C#的代码组织和执行流程,为后面深入探讨提供了基础。

2. Windows Forms界面设计

2.1 Windows Forms的基础知识

2.1.1 Form的设计原理和属性设置

Windows Forms是微软公司提供的一种快速开发Windows桌面应用程序的框架。Form是构成应用程序界面的基础,是所有窗体控件的容器。设计原理上,Form可以理解为一个画布,开发者通过在Form上放置控件来构建用户界面。Form的属性设置是界面设计的基石,比如Size和Location属性决定了窗体的大小和位置,Text属性可以设置窗体标题栏上的文本。

在创建Windows Forms应用时,通常需要对Form进行如下基本设置:

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();

        // 设置窗体标题
        this.Text = "Windows Forms App";
        // 设置窗体大小
        this.Size = new Size(400, 300);
        // 设置窗体位置
        this.Location = new Point(100, 100);
        // 设置窗体背景色
        this.BackColor = Color.White;
    }
}

在上述代码中,我们创建了一个名为 MainForm 的窗体类,并通过构造函数初始化了一些基本属性。这是设置Form属性的典型方法。

2.1.2 控件的种类和使用方法

在Windows Forms中,控件是用户与程序交互的媒介。控件的种类很多,包括按钮(Button)、文本框(TextBox)、标签(Label)、列表框(ListBox)等。每种控件都有其独特的功能和属性,合理地使用这些控件可以有效地创建功能丰富且用户友好的界面。

例如,下面的代码演示了如何添加一个按钮控件,并为其添加点击事件处理程序:

private void MainForm_Load(object sender, EventArgs e)
{
    // 创建一个按钮控件
    Button submitButton = new Button();
    submitButton.Text = "提交";
    submitButton.Location = new Point(100, 150);
    submitButton.Size = new Size(100, 50);
    // 为按钮添加点击事件
    submitButton.Click += new EventHandler(submitButton_Click);
    // 将按钮添加到窗体上
    this.Controls.Add(submitButton);
}

private void submitButton_Click(object sender, EventArgs e)
{
    MessageBox.Show("按钮被点击了!");
}

MainForm_Load 方法中,我们在窗体加载时添加了一个按钮,并设置了其文本、位置和大小。通过订阅 Click 事件,我们指定了当按钮被点击时应当执行的操作。

接下来,让我们探讨如何实现高级界面布局技巧。

2.2 高级界面布局技巧

2.2.1 窗体的自定义布局和样式设计

在Windows Forms中,布局管理器用于管理控件的位置和大小,以实现窗体的自定义布局。布局管理器包括 FlowLayoutPanel TableLayoutPanel 等,这些布局容器可以灵活地对控件进行排列。为了更好地控制控件布局,开发者可以使用布局管理器的属性和方法来精确调整布局。

下面的示例展示了如何使用 TableLayoutPanel 来创建一个表格布局的窗体:

private void InitializeTableLayoutPanel()
{
    TableLayoutPanel营造良好布局 = new TableLayoutPanel();
   良好布局.ColumnCount = 3; // 设置列数
   良好布局.RowCount = 2; // 设置行数
   良好布局.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33F));
   良好布局.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33F));
   良好布局.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 34F));
   良好布局.RowStyles.Add(new RowStyle(SizeType.AutoSize));
   良好布局.RowStyles.Add(new RowStyle(SizeType.AutoSize));

   良好布局.Controls.Add(new Label() { Text = "姓名" }, 0, 0);
   良好布局.Controls.Add(new TextBox(), 1, 0);
   良好布局.Controls.Add(new Label() { Text = "年龄" }, 0, 1);
   良好布局.Controls.Add(new NumericUpDown(), 1, 1);

    this.Controls.Add(良好布局);
}

通过定义列和行的样式,并将标签和文本框添加到对应的单元格中,我们使用 TableLayoutPanel 创建了一个整洁的表格布局。这种布局方式能够很好地适应不同屏幕尺寸,并提供良好的用户体验。

2.2.2 动态界面设计和事件驱动模型

动态界面设计是指在运行时根据用户的操作或者数据的变化来动态地改变界面。这种设计通常需要结合事件驱动模型来实现。在Windows Forms中,几乎所有的用户操作都会触发一个事件,比如按钮点击、文本框内容更改等。开发者可以通过编写事件处理程序来响应这些事件,从而实现动态界面的逻辑。

下面的代码段演示了如何根据用户输入的年龄,动态调整标签显示的内容:

private void numericAge_ValueChanged(object sender, EventArgs e)
{
    int age = (int)((NumericUpDown)sender).Value;
    string message = "您的年龄是:" + age.ToString() + "岁";
    if (age < 18)
    {
        message += ",未成年人禁止操作!";
    }
    else if (age >= 18 && age < 60)
    {
        message += ",请确保您拥有合法操作权限!";
    }
    else
    {
        message += ",请享受您的退休生活!";
    }
    labelAgeStatus.Text = message;
}

在这个例子中,我们为 NumericUpDown 控件添加了一个值变更的事件处理程序。当用户改变控件的值时,程序会根据年龄显示不同的信息。这是一个简单但非常实用的动态界面设计和事件驱动模型的例子。

以上是Windows Forms界面设计的基础和高级技巧。通过合理地使用布局管理器和事件驱动模型,开发者可以设计出既美观又功能强大的应用程序界面。接下来,我们将探讨如何在SQL Server数据库中进行基础操作。

3. SQL Server数据库应用

3.1 SQL Server基础操作

3.1.1 数据库的创建与连接

在本节中,我们将讨论如何在SQL Server中创建和连接数据库。创建数据库是任何数据库驱动的应用程序的第一步。数据库一旦创建,就可以通过SQL Server Management Studio (SSMS) 或其他数据库管理工具连接到它。

创建数据库

要创建一个数据库,您可以使用SQL Server Management Studio (SSMS) 图形用户界面或者直接编写T-SQL脚本。以下是使用T-SQL创建数据库的基本示例:

CREATE DATABASE TestDB;

此命令将创建一个名为 TestDB 的数据库。在执行此操作之前,确保你有足够的权限创建数据库,且你所连接的服务器配置允许创建新的数据库。

连接数据库

连接数据库是任何数据库操作的前提。在SSMS中,你可以通过简单的操作来连接数据库:打开SSMS,点击“连接”,选择“数据库引擎”,然后输入服务器名称、登录凭证等信息。

在C#中,你可以使用 SqlConnection 类来连接数据库。下面的示例代码展示了如何建立与数据库的连接:

using System.Data.SqlClient;

// ...

string connectionString = @"Data Source=(local);Initial Catalog=TestDB;Integrated Security=True";
using(SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();
    // 你可以在这里执行SQL命令
}

在上面的代码中, connectionString 是一个包含连接信息的字符串。它包含了服务器地址( Data Source ), 数据库名称( Initial Catalog ), 以及认证方式( Integrated Security )。

参数说明
  • Data Source 参数用来指定服务器的实例。在本例中,它被设置为 (local) ,表示连接到本地服务器。
  • Initial Catalog 参数用来指定要连接到的数据库的名称,在本例中为 TestDB
  • Integrated Security 参数设置为 True 表示使用Windows身份验证进行连接。

3.1.2 数据表的设计与数据操作

设计良好的数据表是构建稳定和高效数据库应用的关键。在本节中,我们将探讨如何设计数据表以及如何进行基本的数据操作,包括插入、更新、删除和查询。

设计数据表

在设计数据表时,需要考虑以下几个要素:表名、列名、数据类型和约束。下面是一个简单的T-SQL脚本,用于创建一个包含用户信息的数据表:

CREATE TABLE dbo.Users (
    UserID INT PRIMARY KEY IDENTITY(1,1),
    Username NVARCHAR(50) NOT NULL,
    Password NVARCHAR(50) NOT NULL,
    Email NVARCHAR(100) NOT NULL
);

在这个例子中, Users 表有四个字段: UserID (主键)、 Username Password Email UserID 自动递增,表示每条记录的唯一标识。

数据操作

在创建了表之后,我们可以进行插入、查询、更新和删除等操作。下面是一个使用T-SQL对 Users 表执行基本操作的示例:

-- 插入数据
INSERT INTO dbo.Users (Username, Password, Email) VALUES ('user1', 'pass123', 'user1@example.com');

-- 查询数据
SELECT * FROM dbo.Users;

-- 更新数据
UPDATE dbo.Users SET Password = 'newpass123' WHERE UserID = 1;

-- 删除数据
DELETE FROM dbo.Users WHERE UserID = 1;

在C#代码中,你可以使用 SqlCommand 类来执行上述SQL操作。例如:

using System.Data.SqlClient;

// ...

string connectionString = @"Data Source=(local);Initial Catalog=TestDB;Integrated Security=True";
using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();

    // 插入操作
    string insertSql = "INSERT INTO dbo.Users (Username, Password, Email) VALUES (@Username, @Password, @Email)";
    SqlCommand insertCommand = new SqlCommand(insertSql, connection);
    insertCommand.Parameters.AddWithValue("@Username", "user2");
    insertCommand.Parameters.AddWithValue("@Password", "pass456");
    insertCommand.Parameters.AddWithValue("@Email", "user2@example.com");
    insertCommand.ExecuteNonQuery();

    // 查询操作
    string selectSql = "SELECT * FROM dbo.Users";
    SqlCommand selectCommand = new SqlCommand(selectSql, connection);
    SqlDataReader reader = selectCommand.ExecuteReader();
    while (reader.Read())
    {
        Console.WriteLine(reader["UserID"].ToString() + ", " + reader["Username"].ToString());
    }
    reader.Close();
}

在这个代码示例中,我们首先执行了一个插入操作,然后执行了一个查询操作,展示了如何使用参数化查询以防止SQL注入攻击。同样,更新和删除操作也可以使用类似的方式来执行。

参数说明
  • IDENTITY 属性用于 UserID 列,创建自动递增的主键值。
  • PRIMARY KEY 约束用于确保列中的值是唯一的。
  • NOT NULL 约束用来确保列在插入数据时不可为空。

在C#代码中,我们使用了参数化查询来防止SQL注入。这种方法比直接将值拼接到SQL命令字符串中更安全,因为它使用了参数来传递数据,SQL引擎会对这些参数进行适当的处理。

在本小节中,我们学习了如何在SQL Server中创建和连接数据库,设计数据表以及进行基本的数据操作。这些都是构建任何需要数据存储功能的应用程序所必需的技能。在下一小节,我们将深入数据库连接和SQL编程的高级内容。

4. 用户注册与登录功能实现

4.1 用户注册模块的设计

4.1.1 输入验证与信息加密

在实现用户注册功能时,输入验证是确保数据有效性和安全性的首要步骤。用户提交的信息需要通过各种验证,以确保它们符合预期的格式。例如,电子邮件地址必须包含 “@” 符号,用户名和密码必须符合特定的长度要求和复杂性标准。

信息加密在用户注册模块中也非常重要,以确保用户数据的安全。在存储用户密码等敏感信息时,应使用加密技术,如哈希函数和/或盐值,以防止未授权的访问和数据泄露。下面是一个使用C#的示例代码,展示了如何在用户注册时验证输入并加密密码:

using System;
using System.Text;
using System.Security.Cryptography;

public class UserRegistrationService
{
    private const int MinimumPasswordLength = 8;

    public bool RegisterUser(string username, string email, string password)
    {
        if (!IsValidUsername(username))
        {
            throw new Exception("Invalid username.");
        }

        if (!IsValidEmail(email))
        {
            throw new Exception("Invalid email.");
        }

        if (!IsValidPassword(password))
        {
            throw new Exception("Password does not meet complexity requirements.");
        }

        string hashedPassword = HashPassword(password);

        // 这里应将username, email和hashedPassword存储到数据库中
        // ...

        return true;
    }

    private bool IsValidUsername(string username)
    {
        // 这里可以添加更详细的用户名验证逻辑
        return !string.IsNullOrEmpty(username);
    }

    private bool IsValidEmail(string email)
    {
        // 使用正则表达式来验证电子邮件格式
        return Regex.IsMatch(email, @"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$");
    }

    private bool IsValidPassword(string password)
    {
        return !string.IsNullOrWhiteSpace(password) && password.Length >= MinimumPasswordLength;
    }

    private string HashPassword(string password)
    {
        using (var sha256 = SHA256.Create())
        {
            var hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
            return BitConverter.ToString(hashedBytes).Replace("-", "").ToLowerInvariant();
        }
    }
}

在上述代码中, RegisterUser 方法负责处理注册请求。它首先调用验证方法来确保输入的有效性。如果所有输入都通过验证,它将使用 HashPassword 方法将用户密码哈希处理后存储到数据库中。 HashPassword 方法使用SHA-256算法创建一个安全的密码哈希。

4.1.2 注册数据的存储与管理

注册数据的存储与管理是用户注册模块中最为关键的步骤之一。数据应该被安全地存储在数据库中,并且管理机制需要能够处理各种操作,比如数据的查询、更新、删除等。

在存储用户信息时,通常需要考虑以下几点:

  • 使用安全的方法连接到数据库。
  • 选择合适的数据库模型来存储用户数据。
  • 确保用户数据的完整性、一致性和安全性。

C#中通常使用ADO.NET来与数据库进行交互,下面是一个简单示例:

using System.Data.SqlClient;

public class UserDataAccess
{
    private string connectionString = "YourConnectionStringHere";

    public void AddUser(string username, string email, string hashedPassword)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            string query = @"INSERT INTO Users (Username, Email, HashedPassword) VALUES (@Username, @Email, @HashedPassword)";
            using (SqlCommand command = new SqlCommand(query, connection))
            {
                command.Parameters.Add("@Username", SqlDbType.VarChar).Value = username;
                command.Parameters.Add("@Email", SqlDbType.VarChar).Value = email;
                command.Parameters.Add("@HashedPassword", SqlDbType.VarChar).Value = hashedPassword;

                connection.Open();
                command.ExecuteNonQuery();
            }
        }
    }
}

在上述代码中, AddUser 方法负责将新用户的信息插入到数据库的 Users 表中。我们使用参数化查询来防止SQL注入攻击。在执行 command.ExecuteNonQuery() 之前,确保已经建立了数据库连接,并且在数据库连接关闭后清理资源。

4.2 登录验证与会话管理

4.2.1 身份验证机制与安全措施

用户登录验证是用户注册之后,允许用户访问系统资源和功能的过程。身份验证机制应该能够准确地验证用户的身份信息,比如用户名和密码,并且能够防止各种安全威胁,如暴力破解、会话劫持等。

安全措施是确保用户登录过程安全的关键。通常包括以下几点:

  • 防止多次登录失败尝试,使用账户锁定机制。
  • 记录登录失败和成功的尝试,以便进行监控。
  • 使用SSL/TLS加密客户端和服务器之间的通信。
public class UserLoginService
{
    public bool Login(string username, string password)
    {
        // 假设从数据库中检索到的已存储的哈希密码
        string storedHashedPassword = RetrieveHashedPassword(username);

        // 验证输入的密码是否与数据库中的哈希密码相匹配
        if (VerifyPassword(password, storedHashedPassword))
        {
            // 登录成功
            StartSession(username);
            return true;
        }
        else
        {
            // 登录失败
            return false;
        }
    }

    private string RetrieveHashedPassword(string username)
    {
        // 这里应从数据库中检索哈希密码
        // 仅做示例,返回一个固定的哈希值
        return "固定的哈希值";
    }

    private bool VerifyPassword(string inputPassword, string storedHashedPassword)
    {
        // 使用相同的哈希算法对输入的密码重新哈希
        using (var sha256 = SHA256.Create())
        {
            var hashedBytesInput = sha256.ComputeHash(Encoding.UTF8.GetBytes(inputPassword));
            var hashedBytesStored = Convert.FromHexString(storedHashedPassword); // 将字符串哈希转换为字节

            return StructuralComparisons.StructuralEqualityComparer.Equals(hashedBytesInput, hashedBytesStored);
        }
    }

    private void StartSession(string username)
    {
        // 创建用户会话,将用户信息存储在会话中
        // ...
    }
}

4.2.2 会话跟踪与异常处理

在用户登录成功之后,通常会启动一个会话跟踪机制。会话跟踪允许服务器端维持关于客户端状态的信息,并在用户的多个请求之间维护状态。常见的会话跟踪机制包括Cookie和会话状态。

异常处理是确保应用程序在面对意外情况时能够维持正常运行的关键。在用户登录过程中,可能遇到的异常包括数据库连接失败、验证失败等。

public class SessionManager
{
    public void CreateSession(string username)
    {
        // 为用户创建一个新的会话ID
        string sessionId = Guid.NewGuid().ToString();
        // 为用户保存会话信息,例如用户的用户名和会话ID
        // ...

        // 将会话ID作为cookie发送给用户
        // ...
    }

    public bool ValidateSession(string sessionId)
    {
        // 验证会话ID是否有效
        // ...
        return true; // 示例中总是返回true
    }
}

public class UserLoginService
{
    public bool Login(string username, string password)
    {
        try
        {
            // 登录验证逻辑
            // ...

            // 如果验证成功,则创建会话
            SessionManager.CreateSession(username);
            return true;
        }
        catch (Exception ex)
        {
            // 记录异常信息,并通知用户登录失败
            // ...
            return false;
        }
    }
}

在上述代码中, CreateSession 方法负责为成功登录的用户创建一个新的会话,并将相关信息保存起来。会话信息可以存储在服务器端的内存中,也可以存储在数据库中,或者通过会话Cookie来维护。异常处理则使用try-catch块来捕获在登录过程中可能发生的任何异常,并进行适当的处理。

通过以上的步骤和代码实现,可以有效地完成用户注册与登录功能的实现,同时保证了数据的安全性和系统的稳定性。

5. 网络通信基础

5.1 基于TCP/IP的套接字编程

5.1.1 网络协议概述与Socket通信原理

在深入探讨TCP/IP套接字编程之前,我们需要了解网络协议的基本概念和Socket通信的原理。网络协议是一组规则,用于在网络中的设备之间交换数据。TCP/IP是一种广泛使用的协议族,它定义了数据如何在网络中传输以及如何被路由到目的地。

Socket编程是网络通信中的一个核心概念。套接字(Socket)是一个抽象的编程接口,它提供了一种允许程序发送和接收数据的方式,就像将数据传输通过网络上的管道一样。TCP套接字是基于连接的,使用TCP协议保证数据传输的可靠性和顺序性。而UDP套接字则不需要建立连接,适用于对实时性要求高但可以容忍少量数据丢失的应用场景。

5.1.2 客户端与服务器端程序设计

在TCP/IP网络通信中,通常涉及到服务器端和客户端的程序设计。服务器端程序负责监听特定端口,等待来自客户端的连接请求。一旦客户端请求建立连接,服务器端将接受连接并进行数据交换。

以下是一个简单的TCP服务器端和客户端程序设计示例。

TCP服务器端示例代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

public class TcpServer
{
    private TcpListener _tcpListener;
    private int _port = 13000; // TCP端口号

    public TcpServer()
    {
        _tcpListener = new TcpListener(IPAddress.Any, _port);
    }

    public void Start()
    {
        _tcpListener.Start();
        Console.WriteLine("TCP server started on port " + _port + ".");

        while (true)
        {
            Console.WriteLine("Waiting for a connection...");
            TcpClient client = _tcpListener.AcceptTcpClient();
            Console.WriteLine("Connected!");

            // 创建一个线程来处理客户端的请求
            Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClient));
            clientThread.Start(client);
        }
    }

    private void HandleClient(object obj)
    {
        TcpClient client = (TcpClient)obj;
        NetworkStream stream = client.GetStream();

        byte[] buffer = new byte[1024];
        int bytesRead;

        try
        {
            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
            {
                // 将接收到的数据转换为字符串并输出
                string receivedData = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                Console.WriteLine("Received: " + receivedData);

                // 可以在这里添加代码来处理客户端发送的数据
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: " + e.ToString());
        }
        finally
        {
            client.Close();
        }
    }
}
TCP客户端示例代码:
using System;
using System.Net.Sockets;
using System.Text;

public class TcpClientProgram
{
    public static void Main(string[] args)
    {
        TcpClient client = new TcpClient("127.0.0.1", 13000);

        try
        {
            NetworkStream stream = client.GetStream();

            // 发送数据到服务器
            string message = "Hello Server!";
            byte[] data = Encoding.ASCII.GetBytes(message);

            stream.Write(data, 0, data.Length);
            Console.WriteLine("Sent: " + message);

            // 接收服务器的响应
            data = new byte[256];
            int bytes = stream.Read(data, 0, data.Length);
            string responseData = Encoding.ASCII.GetString(data, 0, bytes);
            Console.WriteLine("Received: " + responseData);
        }
        catch (SocketException e)
        {
            Console.WriteLine("SocketException: " + e.ToString());
        }
        finally
        {
            client.Close();
        }
    }
}

5.2 C#中的网络通信类库

5.2.1 使用HttpClient进行HTTP通信

HttpClient 是一个用于发送HTTP请求和接收HTTP响应的类。它提供了一种方便的方式来与Web服务器进行交互。 HttpClient 支持同步和异步操作,并且能够自动处理诸如重定向、HTTP头处理等复杂任务。

以下是一个使用 HttpClient 发送HTTP请求并接收响应的示例代码:

using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    private static readonly HttpClient _httpClient = new HttpClient();

    static async Task Main()
    {
        try
        {
            // 发送GET请求
            HttpResponseMessage response = await _httpClient.GetAsync("http://www.example.com");
            response.EnsureSuccessStatusCode();
            string responseBody = await response.Content.ReadAsStringAsync();

            // 输出响应内容
            Console.WriteLine(responseBody);
        }
        catch(HttpRequestException e)
        {
            Console.WriteLine("\nException Caught!");
            Console.WriteLine("Message :{0} ", e.Message);
        }
    }
}
5.2.2 使用WebSocket实现持久连接

WebSocket提供了一个在客户端和服务器之间建立持久连接的机制。它允许全双工通信,也就是说服务器和客户端可以同时互相发送数据。

以下是一个使用C#中的 WebSocket 类创建WebSocket连接并发送/接收消息的示例代码:

using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var uri = new Uri("ws://echo.websocket.org");
        using (var webSocket = new ClientWebSocket())
        {
            // 连接到WebSocket服务器
            await webSocket.ConnectAsync(uri, CancellationToken.None);
            Console.WriteLine("Connected.");

            // 发送数据到服务器
            string message = "Hello Server!";
            var buffer = Encoding.UTF8.GetBytes(message);
            await webSocket.SendAsync(new ArraySegment<byte>(buffer), 
                                      WebSocketMessageType.Text, 
                                      endOfMessage: true, 
                                      cancellationToken: CancellationToken.None);

            // 接收服务器的响应
            var receiveBuffer = new byte[1024];
            var result = await webSocket.ReceiveAsync(new ArraySegment<byte>(receiveBuffer), 
                                                      CancellationToken.None);

            if (result.MessageType == WebSocketMessageType.Text)
            {
                var receivedText = Encoding.UTF8.GetString(receiveBuffer, 0, result.Count);
                Console.WriteLine("Received Text: " + receivedText);
            }

            // 关闭WebSocket连接
            await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, 
                                       string.Empty, 
                                       CancellationToken.None);
        }
    }
}

这些代码示例展示了如何在C#中使用不同的网络通信协议和类库。理解这些基础知识后,开发者能够构建出更加复杂和健壮的网络通信应用。

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

简介:本项目旨在介绍如何使用C#语言开发一个简易版的即时通讯软件,模拟腾讯QQ的基本功能。项目内容包括使用Windows Forms创建用户界面、利用SQL Server数据库实现注册登录机制、网络通信原理、多线程处理、数据序列化以及安全性措施。该教程不仅提供了详细的开发流程,还深入讲解了多种编程技术的应用,帮助开发者掌握即时通讯系统开发的关键技能。


本文还有配套的精品资源,点击获取
menu-r.4af5f7ec.gif

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐