C#写Socket(二)

来源:互联网 发布:欧莱雅淘宝旗舰店 编辑:程序博客网 时间:2024/05/16 11:53

上一节中对Socket创建连接注释的挺清楚了,这里就不会注释那么清楚了,要是有不太懂的地方可以参考上一节。

这里用一个unity创建一个简单的聊天室

 

还是先贴服务器的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;//EndPoint的命名空间
using System.Net.Sockets;//Socket的命名空间
using System.Text;
using System.Threading.Tasks;

namespace unity聊天室_创建tcp服务器端_01
{
    /*
     * 服务器端
     * 创建socket
     * 绑定ip和端口号
     * 设置监听
     * 等待客户端连接//把这个等待客户端连接的方法放到While中
     * 由于等待到客户端连接,要返回一个Socket类型的对象,将来是要用这个对象和客户端通信的
     * 所以创建一个包含Socket 的类,该类中包含了和库户端通信的方法
     * 用一个List把创建的类保存起来,(会有很多客户端连接过来,所以用list比较方便)
     * 用list保存起来可以很方便的给所有连接的客户端发送消息
     */
    class Program
    {
        static List<Client> clientList = new List<Client>();

        /// <summary>
        /// 广播消息
        /// </summary>
        /// <param name="message"></param>
        public static void BroadcastMessage(string message)
        {
            List<Client> notConnctedList = new List<Client>();
            foreach (var client in clientList)
            {
                if (client.Connected)
                {
                    client.SendMessage(message);//连接的客户端发送消息
                }
                else
                {
                    notConnctedList.Add(client);//没有连接的客户端添加到一个没连接的list里,方便一会把没有连接的删除
                }
            }
            foreach (var item in notConnctedList)
            {
                clientList.Remove(item);//把没有连接的客户端删除,
            }
        }

        static void Main(string[] args)
        {
            //创建Socket
            Socket tcpServer = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);
            //绑定ip和端口号
            tcpServer.Bind(new IPEndPoint(IPAddress.Parse("192.168.35.36"),7788));//这个ip地址根据自己的电脑确定
            //设置监听
            tcpServer.Listen(100);
            Console.WriteLine("连接中...");
            while (true)
            {
                //等待连接,返回一个Socket类型,用这个Socket和连接到的客户端通信
                Socket clientSocket = tcpServer.Accept();
                Console.WriteLine("一个客户端连接过来 !!!");
                //把与每个客户端通信的逻辑(收发消息)放到Client类里进行处理
                Client client = new Client(clientSocket);
                clientList.Add(client);
            }         
        }
    }
}

//下面是服务器端Client类的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace unity聊天室_创建tcp服务器端_01
{
    /// <summary>
    /// 用来跟客户端做通信
    /// </summary>
    class Client
    {
        private Socket clientSocket;//用这个socket和客户端通信
        private Thread t;//定义一个线程,用来处理客户端的数据接收
        private byte[] data = new byte[1024];//这是一个数据容器

        //这个构造在创建Client对象的时候调用(会传递一个Socket对象,就是用这个对象和不同客户端通信的) 顺便开启一个线程接收客户端发来的消息
        public Client(Socket s)
        {
            clientSocket = s;
            //启动一个线程处理客户端的数据接收
            t = new Thread(ReceiveMessage);
            t.Start();
        }
        /// <summary>
        /// 接收数据,并把接收到的消息广播给各个客户端
        /// </summary>
        private void ReceiveMessage()
        {
            //一直接收客户端的数据
            while (true)
            {
                //在接收数据之前,判断一下socket连接是否断开
                if (clientSocket.Poll(10,SelectMode.SelectRead))
                {
                    clientSocket.Close();//关闭当前的连接
                    break;
                }

                int length = clientSocket.Receive(data);//接收数据返回int类型,表示接收了多少字节
                string message = Encoding.UTF8.GetString(data, 0, length);
                //(服务器端在)接收到数据的时候 要把这个数据分发到客户端
                Console.WriteLine("收到了消息:"+ message);
                Program.BroadcastMessage(message);//广播方法 自己写
            }
        }
        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="message"></param>
        public void SendMessage(string message)
        {
            byte[] data = Encoding.UTF8.GetBytes(message);
            clientSocket.Send(data);
        }

        //判断是否连接,
        public bool Connected
        {
            get { return clientSocket.Connected; }
        }

    }
}

 

 

下面是客户端的代码

先编辑好Unity的聊天界面

 

using UnityEngine;
//using System.Collections;
using System.Net.Sockets;
using System.Net;
using System.Text;
using UnityEngine.UI;
using System.Threading;


public class ChatManger : MonoBehaviour {

    public string ipaddress = "192.168.35.36";
    public int port = 7788;

    private Socket clinetSocket;

    public InputField uiInput;
    public Text uiLable;

    private Thread t;
    private byte[] data = new byte[1024];//数据容器
    private string message = "";//用来接收传递过来的消息(服务器广播的消息)

 // Use this for initialization
 void Start () {
        ConnectToServer();
 }
 
 // Update is called once per frame
 void Update () {
        if (message != null && message != "")
        {
            uiLable.text += "\n" + message;
            message = "";//赋值完了清空message
        }
 }
    /// <summary>
    /// 建立数据连接
    /// </summary>
    void ConnectToServer()
    {
        //创建socket
        clinetSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //跟服务器端建立连接
        clinetSocket.Connect(new IPEndPoint(IPAddress.Parse(ipaddress), port));

        //为了方便接收服务器广播的消息,在创建socket的时候在创建一个新的线程用来接收消息
        t = new Thread(ReceiveMessage);
        t.Start();


    }
    /// <summary>
    /// 这个线程方法用来循环接收消息
    /// </summary>
    private void ReceiveMessage()
    {
        while (true)
        {
            if (clinetSocket.Connected == false)
            {
                break;
            }
            int length = clinetSocket.Receive(data);//接收服务器发来的数据
            message = Encoding.UTF8.GetString(data, 0, length);
            //uiLable.text += "\n" + message;//unity中不允许在另一个线程操作unity中的组件
        }
       
    }
    /// <summary>
    /// 发送数据的方法
    /// </summary>
    /// <param name="message"></param>
    void SendMessage(string message)
    {
        byte[] data = Encoding.UTF8.GetBytes(message);
        clinetSocket.Send(data);//发送给服务器
    }
    /// <summary>
    /// 点击发送时调用的方法
    /// </summary>
    public void OnSendButtonClick()
    {
        string value = uiInput.text;
        SendMessage(value);
        uiInput.text = "";
    }
    //当程序结束是关闭连接,clinetSocket
    void OnDestroy()
    {
        clinetSocket.Shutdown(SocketShutdown.Both);//关闭(枚举)
        clinetSocket.Close();//关闭连接
    }
}

 

原创粉丝点击