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#使用Task实现异步方法

    接下来我会详细讲解如何使用C#的Task实现异步方法。 什么是异步方法? 先简单介绍一下什么是异步方法。异步方法指的是在执行某些任务时,不阻塞当前线程,而是开辟新的线程去执行任务,这样能够提高程序的执行效率。C#中实现异步方法的方式有很多,其中就包括Task。 使用Task实现异步方法的步骤 具体实现步骤如下: 构造异步方法调用的签名,签名需要加上async…

    C# 2023年5月15日
    00
  • C# 抓取网页内容的方法

    我来为你详细讲解使用C#抓取网页内容的具体攻略。 一、准备工作 在开始之前,我们需要先引用 System.Net 名称空间,该名称空间为我们提供了一系列的网络操作类。 以下是代码示例: using System.Net; 二、HTTP请求 接下来我们需要构造一个 HTTP 请求,通过该请求来获取网页内容。通常我们抓取网页内容所用的 Http 请求类型是 Ge…

    C# 2023年5月31日
    00
  • BackBone及其实例探究_动力节点Java学院整理

    BackBone及其实例探究攻略 简介 Backbone是一个轻量级的JavaScript框架,可用于建立单页Web应用程序。它提供了一个基于Restful JSON接口的MVC(模型-视图-控制器)框架。Backbone实现了模块化开发,提供了事件绑定、复合模型、集合等功能。通过使用Underscore库,Backbone实现了诸如数据绑定和快速原型等功能…

    C# 2023年5月31日
    00
  • 详解VS2017 Linux 上.NET Core调试

    详解VS2017 Linux 上.NET Core调试 在本攻略中,我们将详细介绍如何使用Visual Studio 2017在Linux上调试.NET Core应用程序。我们将介绍如何配置调试环境、如何在Visual Studio中设置调试器,并提供两个示例说明。 配置调试环境 在将.NET Core应用程序调试到Linux上之前,需要进行以下准备工作: …

    C# 2023年5月16日
    00
  • C#仪器数据文件解析Excel文件的方法浅析(xls、xlsx)

    C#仪器数据文件解析Excel文件的方法浅析 在C#编程中,经常需要从仪器导出的数据文件进行Excel格式的解析。本文将针对xls和xlsx两种常见的Excel文件格式,分别进行简单的介绍。 Excel文件的格式说明 Excel文件主要包括两个文件格式,即xls和xlsx。其中,xls文件是Excel 97-2003版本的二进制文件格式,而xlsx文件是Ex…

    C# 2023年5月31日
    00
  • ASP.NET中的C#基础知识

    ASP.NET中的C#基础知识 ASP.NET是一种广泛使用的Web应用程序框架,而C#是一种常用的ASP.NET开发语言。在ASP.NET的开发过程中,必须掌握C#的基础知识才能进行编码和开发。本文将介绍ASP.NET中的C#基础知识,帮助您更好地理解和掌握ASP.NET开发中的C#应用。 数据类型 C#中的数据类型与其他编程语言类似,包括int、floa…

    C# 2023年5月15日
    00
  • 如何用C#找出数组中只出现了一次的数字

    下面是如何用C#找出数组中只出现了一次的数字的完整攻略。 问题描述 在一个整数数组中,除了一个数字只出现一次之外,其他数字都出现了两次。请找出那个只出现一次的数字。 解题思路 由于数组中只有一个数字出现一次,其他数字都出现了两次,那么可以先将数组中的数字进行排序,然后遍历这个排序后的数组,每次比较当前数字和它后面的数字是否相同,如果不相同则说明当前数字只出现…

    C# 2023年6月1日
    00
  • 基于C#生成随机数示例

    生成随机数是很常见的一种需求,无论是在游戏、金融还是科学领域,都需要使用到随机数。C#作为一门强大的编程语言,自然也提供了非常方便的方法来生成随机数。 下面是生成随机数的完整攻略。 步骤一 – 声明随机数生成器 首先,我们需要创建 Random 类型的对象,来帮助我们生成随机数。 在 C# 中,我们可以使用以下代码生成随机数生成器: Random rando…

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