C#基于Socket实现简单聊天室功能

因为这段时间在学习Socket,所以就试着写了一个简单的聊天室。主要分为服务器端和多个客户端。利用服务器端作数据中转站,实现消息群发。

1、服务器端有两个类:

using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

namespace 聊天室_Socket_TCP_服务器端
{
    class Program
    {
        static List<Client> clients = new List<Client>();
        static List<Client> notClients = new List<Client>();

        /// <summary>
        /// 广播消息
        /// </summary>
        /// <param name="message"></param>
        public static void CastMessageTOAllConnetedClients(string message)
        {
            foreach (var client in clients)
            {
                if (client.Conneted)
                {
                    client.CastMessage(message);
                }
                else
                {
                    notClients.Add(client);
                }
            }
            foreach (var temp in notClients)
            {
                clients.Remove(temp);
            }
        }

        static void Main(string[] args)
        {         
            Socket tcpSever = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            tcpSever.Bind(new IPEndPoint(IPAddress.Parse("192.168.1.2"), 8899));
            tcpSever.Listen(100);//监听是否有客户端发起连接
            Console.WriteLine("Begin to listen...");

            while (true)
            {
                Socket clientSocket = tcpSever.Accept();
                if (clientSocket!=null)
                {
                    Console.WriteLine("A client has connneted...");
                    Client client = new Client(clientSocket);//将每个新创建的连接通信放于client类做通信
                    clients.Add(client);
                }
            }
            Console.ReadKey();
        }
    }
}
using System;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace 聊天室_Socket_TCP_服务器端
{
    /// <summary>
    /// 利用该类和客户端做通信
    /// </summary>
    class Client
    {
        public Socket clientSocket;
        private Thread mesManageTherad; 
        private byte[] bufffer=new byte[20];

        public Client(Socket soc)
        {
            clientSocket = soc;
            //由于消息是不断发送的,需要多次进行处理。这里开一个线程,专门用来处理消息。
            mesManageTherad = new Thread(MessageSendFromClient);
            mesManageTherad.Start();
        }

        private void MessageSendFromClient()
        {
            //开启的线程一直检测客户端客户端发过来的消息
            while (true)
            {
                //判断连接是否断开,  SelectMode.SelectRead读状态模式。
                //poll已断开返回true
                if (clientSocket.Poll(10,SelectMode.SelectRead)==true)    
                {
                    clientSocket.Close();
                    break;//终止本线程
                }
                    int byteNum = clientSocket.Receive(bufffer);//从客户端接受消息
                    string mes = Encoding.UTF8.GetString(bufffer, 0 , byteNum);
                    Console.WriteLine("客户端发送过来的消息:"+mes);
                    //广播消息出去给每个客户端
                    Program.CastMessageTOAllConnetedClients(mes);//对CastMessage的一层封装
            }
        }

        /// <summary>
        /// Send messages to Clients
        /// </summary>
        public void CastMessage(string message)
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            clientSocket.Send(data);
        }

        /// <summary>
        /// 判断是否断开连接
        /// </summary>
        public bool Conneted
        {
            get
            {
                return clientSocket.Connected;
            }
        }

    }
}

服务器端逻辑:

这里的服务器主要负责建立连接,接受客户端消息,广播客户端发来的消息。
服务器通过socket对象绑定服务器IP和相应端口号(端口号自己开,没有被其他软件占用就好),通过Listen监听和服务器socket对象的Accept方法捕捉连接到服务器的客户端socket,将捕捉到的客户端socket放入List集合中方便统一管理和后面的消息群发。
关于捕捉到的客户端socket的逻辑处理放在了Client类中统一管理。
Client类将收到客户端的消息进行接受,在Client中开启一个线程用于不断得检测是否有新消息从客户端发送过来,若有消息发送过来则通过CastMessageTOAllConnetedClients方法(对socket对象的Send方法的封装)发送给每一个客户端。

2.客户端

客户端是在Unity中使用NGUI插件简单开发的一个聊天界面。把脚本挂在NGUI控件上即可。客户端主要负责显示消息,发送消息,接收消息。

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;

public class ChatManager : MonoBehaviour {

    private string _ipAdress = "192.168.1.2";
    private int _port=8899;
    EndPoint remotPoint;
    Socket clientSocket;
    public UIInput buttonInput;
    private bool isCanSend=false;
    private string buttonMessage=null;

    Thread receiveThread;
    byte[] bufferReceive = new byte[1024];
    public UILabel chatWindowLable;
    private string message = "";//默认为空串

    // Use this for initialization
    void Start () {
        ConnetToSever(_ipAdress, _port);//与服务器建立连接
    }

    // Update is called once per frame
    void Update () {
        if (message!=null&&message!="")
        {
            chatWindowLable.text += "\n" + message;
            message = "";//清空消息
        }
    }

    void ConnetToSever(string ipadress,int port)
    {
        clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        remotPoint = new IPEndPoint(IPAddress.Parse(ipadress),port);
        //建立连接
        clientSocket.Connect(remotPoint);
        //因为是一直在准备接受的状态,所以开启一个线程来负责处理接受消息
        receiveThread = new Thread(ReceiveMessageFormSever);
        receiveThread.Start();

    }

    private new void SendMessage(string message)
    {
        byte [] buffer= Encoding.UTF8.GetBytes(message);
        clientSocket.SendTo(buffer,remotPoint);
    }

    public void OnSendButtonClickS()
    {

        if (buttonInput.value!=null)
        {
            buttonMessage = buttonInput.value;
        }
        else
        {
            buttonMessage = "输入框为空!";
        }
        SendMessage(buttonMessage);
        buttonInput.value = "";
    }

    private void ReceiveMessageFormSever()
    {
        while (true)
        {
            if (clientSocket.Connected)
            {
                int length = clientSocket.Receive(bufferReceive);
                message = Encoding.UTF8.GetString(bufferReceive, 0, length);
                //ps:不要在单独的线程里面操作unity组件
            }
            else
            {
                break;
            }
        }
    }
}

在客户端中同样有一个socket对象,这个对象通过ConnetToSever方法连接到服务器。在这里,假如某个客户端通过输入框输入文本被客户端脚本捕捉,它将以流的方式发送到服务器,服务器接受到文本,并在服务器端将文本群发至每个客户端。服务器开设了一个线程专门用于捕捉客户端发来的消息,当然,客户端也有相应的线程时刻捕捉服务器发来的消息。消息被客户端捕捉到了,就可以显示在各自的客户端界面上了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • C#聊天程序服务端与客户端完整实例代码

    本文所述为基于C#实现的多人聊天程序服务端与客户端完整代码.本实例省略了结构定义部分,服务端主要是逻辑处理部分代码,因此使用时需要完善一些窗体按钮之类的. 先看服务端代码如下: using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Net; using

  • C#基于Socket的TCP通信实现聊天室案例

    本文实例为大家分享了vue + element ui实现锚点定位的具体代码,供大家参考,具体内容如下 一.Socket(套接字)通信概念 套接字(socket)是通信的基石,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信,是支持TCP/IP协议的网络通信的基本操作单元.它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口. 应用层通过传输层进行数据

  • ASP.net(C#)实现简易聊天室功能

    本文实例为大家分享了ASP.net(C#)实现简易聊天室功能的具体代码,供大家参考,具体内容如下 1.搭建框架 <html > <head>     <title>聊天系统</title> </head>     <frameset rows="80%,20%" >           <frameset cols="20%,80%">           <frame src

  • C#简单聊天室雏形

    本文实例为大家分享了C#简单聊天室雏形的具体代码,供大家参考,具体内容如下 程序使用的控制台的黑窗口模拟程序,第一次涉及网络编程,写出来方便以后查阅,代码很简单首先是服务器端的代码: public class ServerControl     {         private Socket serverSocket;         public ServerControl()         {             serverSocket = new Socket(AddressFa

  • C#使用Socket实现本地多人聊天室

    本文实例为大家分享了C#使用Socket实现本地多人聊天室的具体代码,供大家参考,具体内容如下 [脚本一:Server端] 使用本机地址:127.0.0.1 完整代码 using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;   namespace ConsoleApp1 {     p

  • C#使用WebSocket实现聊天室功能

    WebSocket介绍 WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. 在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道.两者之间就直接可以数据互相传送. 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据. 当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发

  • c#基于WinForm的Socket实现简单的聊天室 IM

    1:什么是Socket 所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象. 一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制. 从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口. 2:客服端和服务端的通信简单流程 3:服务端Code: using System; using System.Collections.Generic; using Sys

  • C#实现简易多人聊天室

    本文实例为大家分享了C#实现简易多人聊天室的具体代码,供大家参考,具体内容如下 只有一个群聊的功能 服务端 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Net.Sockets; using System.Te

  • C#制作简单的多人在线即时交流聊天室

    实现网页版的在线聊天室的方法有很多,在没有来到HTML5之前,常见的有:定时轮询.长连接+长轮询.基于第三方插件(如FLASH的Socket),而如果是HTML5,则比较简单,可以直接使用WebSocket,当然HTML5目前在PC端并没有被所有浏览器支持,所以我的这个聊天室仍是基于长连接+长轮询+原生的JS及AJAX实现的多人在线即时交流聊天室,这个聊天室其实是我上周周末完成的,功能简单,可能有些不足,但可以满足在线即时聊天需求,分享也是给大家提供一个思路,大家可以基于此来实现更好的在线即时聊

  • 分享一个C#编写简单的聊天程序(详细介绍)

    引言 这是一篇基于Socket进行网络编程的入门文章,我对于网络编程的学习并不够深入,这篇文章是对于自己知识的一个巩固,同时希望能为初学的朋友提供一点参考.文章大体分为四个部分:程序的分析与设计.C#网络编程基础(篇外篇).聊天程序的实现模式.程序实现. 程序的分析与设计 1.明确程序功能 如果大家现在已经参加了工作,你的经理或者老板告诉你,"小王,我需要你开发一个聊天程序".那么接下来该怎么做呢?你是不是在脑子里有个雏形,然后就直接打开VS2005开始设计窗体,编写代码了呢?在开始之

随机推荐