C#使用Socket实现局域网聊天

C#使用Socket实现局域网聊天攻略

简介

本攻略将介绍如何使用C#中的Socket类实现基于局域网的聊天功能。在该聊天室中,客户端和服务器端都需要使用Socket类来完成通信功能。在进入具体实现前,需要先说明一些基础概念和准备工作。

基础概念

  • Socket:Socket是实现网络通信的底层操作。它是位于传输层的,用于实现网络应用程序之间的双向通信。

  • IP地址:计算机在网络中的位置。IP地址由32位二进制数组成,通常用点分十进制表示。

  • 端口:是网络通信时用来识别服务的数字,通常是16位的整数。端口有两个范围:从0到1023的端口是系统用的,应用程序一般不能使用;从1024到65535的端口是留给应用程序使用。

准备工作

在开始实现聊天功能前,需要先准备好Visual Studio开发环境,选择合适的.NET框架(推荐使用.NET Framework 4.0及以上)以及安装Common.Logging库,方便后面的日志输出。

实现

服务端

在服务端,我们需要做如下操作:

  1. 创建一个Socket对象,指定地址族(AF_INET)和套接字类型(SOCK_STREAM),并绑定到本地IP地址和端口号上。
private static void StartServer()
{
    try
    {
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 1234);
        Socket listener = new Socket(AddressFamily.InterNetwork,
                                     SocketType.Stream, ProtocolType.Tcp);

        listener.Bind(localEndPoint);
        listener.Listen(10);
        Console.WriteLine("Waiting for client...");

        while (true)
        {
            Socket handler = listener.Accept();
            ReceiveMessage(handler);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}
  1. 监听端口,接受客户端连接请求。

  2. 收到客户端发送的消息后,解析消息并进行回复。

private static void ReceiveMessage(Socket handler)
{
    byte[] bytes = new byte[1024];
    int bytesRec = handler.Receive(bytes);
    string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);

    Console.WriteLine("Received message: {0}", data);

    byte[] msg = Encoding.ASCII.GetBytes("Server received message");
    handler.Send(msg);

    handler.Shutdown(SocketShutdown.Both);
    handler.Close();
}

以上为服务端的主要代码实现。其中,ReceiveMessage会解析客户端发送的消息并进行回复。

客户端

在客户端,我们需要做如下操作:

  1. 创建一个Socket对象,指定地址族(AF_INET)和套接字类型(SOCK_STREAM),并连接到服务端的IP地址和端口号上。
private static void StartClient()
{
    try
    {
        IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint remoteEP = new IPEndPoint(ipAddress, 1234);

        Socket sender = new Socket(AddressFamily.InterNetwork,
                                   SocketType.Stream, ProtocolType.Tcp);

        sender.Connect(remoteEP);
        Console.WriteLine("Connected to server...");

        SendMessage(sender);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
}
  1. 向服务端发送消息,并接收服务端的回复。
private static void SendMessage(Socket sender)
{
    byte[] msg = Encoding.ASCII.GetBytes("Client sending message");
    sender.Send(msg);

    byte[] bytes = new byte[1024];
    int bytesRec = sender.Receive(bytes);
    string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);

    Console.WriteLine("Server reply: {0}", data);

    sender.Shutdown(SocketShutdown.Both);
    sender.Close();
}

以上为客户端的主要代码实现。SendMessage会向服务端发送消息,并接收服务端的回复。

示例1

在示例1中,我们将开启一个控制台程序作为服务端,然后开启一个或多个客户端。在控制台中输入消息,并在客户端之间进行消息的传递。示例代码如下:

服务端

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

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            StartServer();
        }

        private static void StartServer()
        {
            try
            {
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 1234);
                Socket listener = new Socket(AddressFamily.InterNetwork,
                                             SocketType.Stream, ProtocolType.Tcp);

                listener.Bind(localEndPoint);
                listener.Listen(10);
                Console.WriteLine("Waiting for client...");

                while (true)
                {
                    Socket handler = listener.Accept();
                    ReceiveMessage(handler);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private static void ReceiveMessage(Socket handler)
        {
            byte[] bytes = new byte[1024];
            int bytesRec = handler.Receive(bytes);
            string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);

            Console.WriteLine("Received message: {0}", data);

            byte[] msg = Encoding.ASCII.GetBytes("Server received message");
            handler.Send(msg);

            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }
    }
}

客户端

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

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            StartClient();
        }

        private static void StartClient()
        {
            try
            {
                IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
                IPAddress ipAddress = ipHostInfo.AddressList[0];
                IPEndPoint remoteEP = new IPEndPoint(ipAddress, 1234);

                Socket sender = new Socket(AddressFamily.InterNetwork,
                                           SocketType.Stream, ProtocolType.Tcp);

                sender.Connect(remoteEP);
                Console.WriteLine("Connected to server...");

                SendMessage(sender);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        private static void SendMessage(Socket sender)
        {
            byte[] msg = Encoding.ASCII.GetBytes("Client sending message");
            sender.Send(msg);

            byte[] bytes = new byte[1024];
            int bytesRec = sender.Receive(bytes);
            string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);

            Console.WriteLine("Server reply: {0}", data);

            sender.Shutdown(SocketShutdown.Both);
            sender.Close();
        }
    }
}

示例2

在示例2中,我们将基于Window Form应用程序实现聊天功能。代码如下:

服务端

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication
{
    public partial class ServerForm : Form
    {
        private Thread listenerThread;
        private Socket listener;
        bool done = false;

        public ServerForm()
        {
            InitializeComponent();
        }

        private void Btn_Start_Click(object sender, EventArgs e)
        {
            StartServer();
        }

        private void StartServer()
        {
            try
            {
                IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, 1234);
                listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                listener.Bind(localEndPoint);
                listener.Listen(10);

                listenerThread = new Thread(ListenThread);
                listenerThread.Start();

                listBox1.Items.Add("Waiting for connection...");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ListenThread()
        {
            while (!done)
            {
                try
                {
                    Socket handler = listener.Accept();
                    ReceiveMessage(handler);
                }
                catch { }
            }
        }

        private void ReceiveMessage(Socket handler)
        {
            byte[] bytes = new byte[1024];
            int bytesRec = handler.Receive(bytes);
            string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);

            listBox1.Invoke((MethodInvoker)delegate {
                listBox1.Items.Add(data);
            });

            byte[] msg = Encoding.ASCII.GetBytes("Message received on server: " + data);
            handler.Send(msg);

            handler.Shutdown(SocketShutdown.Both);
            handler.Close();
        }

        private void ServerForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            done = true;
            listenerThread.Abort();
            listener.Close();
        }
    }
}

客户端

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication
{
    public partial class ClientForm : Form
    {
        private Socket client;

        public ClientForm()
        {
            InitializeComponent();
        }

        private void Btn_Connect_Click(object sender, EventArgs e)
        {
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(txt_IP.Text), 1234);

            try
            {
                client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                client.Connect(remoteEP);
                MessageBox.Show("Connected to server...");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Btn_Send_Click(object sender, EventArgs e)
        {
            if (client != null && client.Connected)
            {
                byte[] msg = Encoding.ASCII.GetBytes(txt_Message.Text);
                client.Send(msg);

                byte[] bytes = new byte[1024];
                int bytesRec = client.Receive(bytes);
                string data = Encoding.ASCII.GetString(bytes, 0, bytesRec);

                MessageBox.Show(data);
            }
            else
            {
                MessageBox.Show("Not connected to server...");
            }

            txt_Message.Clear();
        }

        private void ClientForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (client != null && client.Connected)
            {
                client.Shutdown(SocketShutdown.Both);
                client.Close();
            }
        }
    }
}

以上为基于Windows Form应用程序的聊天应用程序实现示例。其中,服务端代码基本与控制台程序相同,只是添加了对界面控件的调用。客户端的实现相对简单,只需完成连接和发送消息的操作。

总结

本攻略介绍了如何使用C#中的Socket类实现基于局域网的聊天功能。通过示例程序的使用,可以加深对Socket通信的理解,并掌握相关编程技能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C#使用Socket实现局域网聊天 - Python技术站

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

相关文章

  • 如何在C#中集成Lua脚本

    如何在C#中集成Lua脚本 Lua是一种轻量级脚本语言,它被广泛应用于游戏编程、嵌入式系统和工业自动化等领域。在C#中集成Lua脚本可以使开发者更加灵活地扩展应用程序的功能。下面是详细的攻略: 步骤一:下载并安装Lua库 在http://www.lua.org/download.html官网上下载适合您系统的Lua库并解压到本地目录,例如C:\Lua。 步骤…

    C# 2023年5月15日
    00
  • ASP.NET Core实现文件上传和下载

    ASP.NET Core 实现文件上传和下载 在 ASP.NET Core 中,可以使用多种方式实现文件上传和下载。本攻略将详细介绍如何在 ASP.NET Core 中实现文件上传和下载,并提供多种上传方式的示例。 步骤一:编写文件上传代码 在 ASP.NET Core 中,可以使用 IFormFile 接口实现文件上传。以下是一个简单的文件上传示例: [H…

    C# 2023年5月17日
    00
  • asp.net 文件下载的通用方法

    ASP.NET 是一个强大的 Web 应用程序框架,可用于创建各种类型的 Web 应用程序。如果你需要在应用程序中实现文件下载功能,下面是一套通用的方法,能够帮助你轻松达成目标。 使用 Response.TransmitFile 方法实现文件下载 第一种实现文件下载的方法是使用 Response.TransmitFile 方法。这种方法的优点是非常简单易用,…

    C# 2023年6月3日
    00
  • C#文件非占用读取与帮助类FileHelper

    C#的FileHelper类库提供了许多方便的方法来处理文件读写操作,FileHelper类库中的File类封装了很多文件读写的方法,同时还提供了非占用读取文件的方法,可以有效防止文件被占用而无法进行读取或写入操作。 非占用读取文件 在进行文件读写操作时,有时候文件可能被其他应用程序或者进程占用而无法进行读写操作。FileHelper类库提供了一种解决方法:…

    C# 2023年6月1日
    00
  • C#托管堆对象实例包含内容分析

    C#托管堆对象实例包含内容分析 在C#中,对象实例是存储在堆上的,而且它们往往包含各种复杂的属性和字段。在这里,我们将探讨如何分析这些对象实例包含的内容。 调试工具 在C#中,Visual Studio是最常用的调试工具之一。使用Visual Studio,我们可以使用调试器来分析对象实例。以下是一些常用的调试器窗口: Locals窗口:此窗口显示当前方法中…

    C# 2023年6月1日
    00
  • 总结十条.NET异常处理建议

    下面我将对如何总结十条.NET异常处理建议进行详细讲解。在.NET应用程序中,正确处理异常异常是保证应用程序稳定性和可靠性的关键,可以避免应用程序出现崩溃和数据丢失等问题。因此,我们需要总结出一些通用的.NET异常处理建议。 1. 记录异常日志 在捕捉异常后,我们需要记录异常日志来帮助我们更快地找到问题。记录异常日志的方式有很多,例如使用log4net和NL…

    C# 2023年5月15日
    00
  • c#实现数据库事务示例分享

    下面是关于“C#实现数据库事务示例分享”的详细攻略。 什么是数据库事务 事务是指作为单个逻辑工作单元执行的一连串操作。 在关系型数据库中,一个事务必须具有四个特性,即:原子性、一致性、隔离性和持久性。 原子性:事务作为一个整体来执行,事务中的操作要么全部完成,要么全部不完成。 一致性:在事务开始和结束时,都必须使数据的完整性保持一致。 隔离性:事务执行过程中…

    C# 2023年6月1日
    00
  • C#读写文件的方法汇总

    C#读写文件的方法汇总 在C#编程中,读写文件是一项非常常见的操作。本文将介绍C#语言中常用的文件读写方法。 1. FileStream类 FileStream是.NET Framework中用于读取、写入和操作文件的类。以下是使用FileStream类进行文件读写的示例代码: 读取文件 string path = @"C:\test.txt&qu…

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