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# 标准事件流实例代码

    首先,我们需要了解什么是 C# 标准事件流。C# 标准事件流是一种事件源和事件处理程序之间的机制,允许一个或多个事件处理程序能够对事件进行处理。 下面是一个 C# 标准事件流实例代码的完整攻略: 1. 定义事件和事件处理程序 首先,我们需要定义一个事件和至少一个事件处理程序。在这个例子中,我们定义了一个名为 ButtonClick 的事件和一个名为 OnBu…

    C# 2023年6月7日
    00
  • Java与JavaScript前后端实现手机号验证码一键注册登陆抖音流程

    Java与JavaScript前后端实现手机号验证码一键注册登陆抖音流程 1. 前言 移动互联网时代的到来,改变了人们的生活方式,移动应用程序的流行使得手机成为了人们必不可少的日常工具之一。在移动应用程序的开发中,既要考虑到用户的体验,又要考虑到数据的安全性,因此注册登录及验证码功能至关重要。本篇文章主要介绍在Java与JavaScript前后端实现手机号验…

    C# 2023年5月31日
    00
  • jQuery ajax调用webservice注意事项

    在使用jQuery调用Web服务时,需要注意一些事项,以确保调用成功并获得正确的响应。本文将提供详细的“jQuery ajax调用Web服务注意事项”的完整攻略,包括如何正确设置Web服务、如何处理Web服务响应以及两个示例。 设置Web服务 在使用jQuery调用Web服务时,需要正确设置Web服务。以下是正确设置Web服务的步骤: 在Web服务中启用PO…

    C# 2023年5月15日
    00
  • C#编程总结(一)序列化总结

    下面是关于“C#编程总结(一)序列化总结”的完整攻略,包含两个示例。 1. 序列化总结 在C#编程中,序列化是将对象转换为可存储或可传输格式的过程。反序列化是将序列化的数据转换回对象的过程。C#提供了多种序列化方式,包括二进制序列化、XML序列化和JSON序列化等。以下是C#编程中序列化的总结: 1.1 二进制序列化 二进制序列化是将对象转换为二进制格式的过…

    C# 2023年5月15日
    00
  • Unity实现UI光晕效果(发光效果)

    接下来我将为您介绍如何在Unity中实现UI光晕效果(发光效果)的完整攻略。本攻略中,我将提供两个示例说明来帮助您更好地理解如何实现UI光晕效果。 一、准备工作 在开始实现UI光晕效果之前,我们需要进行一些准备工作: 1. 创建UI元素 我们需要在Unity中创建一个UI元素作为展示光晕效果的对象。您可以按下快捷键“Ctrl + Shift + N”创建一个…

    C# 2023年6月3日
    00
  • c# 实现汉诺塔游戏

    C#实现汉诺塔游戏攻略 思路分析 在讲解C#实现汉诺塔游戏之前,我们先来了解一下它的思路。 汉诺塔游戏是一种经典的递归算法,基本思路如下: 假设有A、B、C三条柱子,A柱子上有n个不同大小的盘子,盘子大小由下到上依次变小,现在要求将A柱子上的盘子移动到C柱子上,移动过程中可以借助B柱子,但每次只能移动最上面的盘子,并且大盘子不能放在小盘子上面。 例如,当有三…

    C# 2023年5月15日
    00
  • Entity Framework Core 大小写敏感处理

      可以使用’StringComparison’吗? 在数据库查询操作中,不可避免去考虑字母大小写的问题,比如要在Movie表中查找“X-Men”这部电影,为了不区分字母大小写,按照Linq to memory的习惯,可能会写出如下代码: DbContext.DbSet<Movie>  .Where(item => string.Equal…

    C# 2023年4月19日
    00
  • c# 单例模式的实现方法

    C#中的单例模式是面向对象编程中比较常用的模式,它可以确保一个类在整个系统中仅有一个实例,并且提供全局访问点。下面是单例模式的实现方法的完整攻略。 单例模式的实现方法 在C#中实现单例模式的一般步骤包括: 实现一个静态私有变量来保存该类的唯一实例。 实现一个公共的静态方法作为访问该类唯一实例的入口。 具体实现方法分为以下几个步骤: 步骤1:定义单例类 pub…

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