Socket笔记(二)

4.基于TCP协议的unity聊天室Demo

1.服务器一般都是买的服务器地址。这里我们用第一节VS写的服务器模拟;
如果从第一节做下来的,直接启动TCP服务器就行了。
否则打开VS,新建控制台应用,把上面第一节的代码复制粘贴上去,启动服务器。
如果启动成功是这样的画面:
在这里插入图片描述
2.接下来我们用Unity做一个聊天室客户端
打开Unity,新建一个项目,项目名字UnityClient(其他名字也行)
在这里插入图片描述
新建一个c#脚本。名字就Client,完整代码如下

using System;
using System.Collections;
using System.Collections.Generic;
usingSystem.Net;
usingSystem.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using UnityEngine.UI;

public class Client : MonoBehaviour {

    //这里填要连接的ip
    private string ip = "10.198.1.15";
    //这里填端口号
    private int port = 9900;
    public InputField Name_inputField;
    public Text ConnectText;
    public InputField chat_inputField;
    public Text ChatText;
    private Socket ClientSocket;
    private String TmpMessage = null;


   // 更新并显示接收的数据
    private void Update()
    {
        if (TmpMessage != null)
        {
            ChatText.text += System.Environment.NewLine+ TmpMessage;
                //+ TmpMessage;
            TmpMessage = null;
        }
    }


    //这里我们不自动连接服务器,写一个方法用来连接服务器
    public void Connect()
    {
        if (Name_inputField.text == "")
        {
            ConnectText.text = "连接服务器失败,请输入用户名";
        }
        else
        {
            try
            {
                //创建Socket
                ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //连接服务器
                ClientSocket.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
                Thread t = new Thread(ReceiveMessage);
                t.Start();
                //把自己的名字发送给服务器
                SendMsg(Name_inputField.text);
                //Debug.LogError(Name_inputField.text);
                ShowMessage("连接服务器成功");
            }
            catch (Exception e)
            {
                //捕捉异常并显示
                ShowMessage("服务器未启动或ip地址错误");
            }
        }
    }


    //这个方法用来显示提示信息
    private void ShowMessage(string msg)
    {
        ConnectText.text = msg;
    }


    //这是封装的一个发送消息的方法,传入一个字符串就可以发给服务器了
    private void SendMsg(string msg)
    {
        try
        {
            byte[] SendData = Encoding.UTF8.GetBytes(msg);
            ClientSocket.Send(SendData);
        }
        catch (Exception e)
        {
            Debug.LogError(e.ToString());
            ShowMessage("消息发送失败");
        }
    }


    //这个方法是给发送按钮调用的方法
    public void SendButtonFunc()
    {
        //把输入框的字符串发给服务器
        SendMsg(chat_inputField.text);
        //输入框清空
        chat_inputField.text = "";
    }


    //这是用来接收消息的方法
    private void ReceiveMessage()
    {
        //用一个while循环不停的接收
        while (true)
        {
            //判断一下,如果连接断开了就不接收了
            if (ClientSocket.Connected == false)
            {
                break;
            }
            //接收服务端的消息
            byte[] ReceivedData = new byte[1024];
            int length = ClientSocket.Receive(ReceivedData);
            string ReceivedMessage = Encoding.UTF8.GetString(ReceivedData, 0, length);
            Debug.LogError(ReceivedMessage);
            TmpMessage = ReceivedMessage;
        }
    }

    private void OnApplicationQuit()
    {
        ClientSocket.Shutdown(SocketShutdown.Both);
        ClientSocket.Close();
    }
}

接下来绑定按钮的方法和添加组件:

按名字拖进去:
在这里插入图片描述
找到按钮,添加方法:

发送按钮 :
在这里插入图片描述
连接服务器按钮:
在这里插入图片描述
客户端的工作就做完了

服务器的代码要做小小的改动。因为加入了客户端的名字功能:

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

namespace TCP_Sever
{

    class ClientedSocket
    {
            //填加了一个用户名字的是有变量
        private String UserName = null;
        private Socket clientedSocket;
        private Thread t;
        private byte[] ReceivedData = new byte[1024];
        public ClientedSocket(Socket ClientedSocket)
        {
            this.clientedSocket = ClientedSocket;
            //启动一个线程,处理客户端的数据接收
            t = new Thread(ReceiveMessage);
            t.Start();
        }


        private void ReceiveMessage()
        {
            try
            {
                //一直接收
                while (true)
                {
                    //在接收数据之前 判断一下Socket连接是否断开
                    if (clientedSocket.Poll(10, SelectMode.SelectRead))
                    {
                        Console.WriteLine("断开连接");
                        clientedSocket.Shutdown(SocketShutdown.Both);
                        clientedSocket.Close();
                        break;
                    }
                    int length = clientedSocket.Receive(ReceivedData);
                    string ReceivedMessage = Encoding.UTF8.GetString(ReceivedData, 0, length);
                                   //当用户名为空时,给用户名赋值
                    if (UserName==null)
                    {
                        UserName = ReceivedMessage;
                        Console.WriteLine("Client setName:"+ UserName);
                    }
                         //不为空就广播消息
                    else
                    {      
                        string msg = UserName + ":" + ReceivedMessage;
                        Console.WriteLine(msg);
                        //数据分发:
                        Program.BroadCastMessage(msg);
                    }
                }
            }
            catch(Exception e)
            {
                Console.WriteLine(e);
                clientedSocket.Shutdown(SocketShutdown.Both);
                clientedSocket.Close();
            }
        }


        public void SendMessage(string msg)
        {
            byte[] SendData = Encoding.UTF8.GetBytes(msg);
            clientedSocket.Send(SendData);
        }


        public bool Connect()
        {           
            return clientedSocket.Connected;
        }
    }
}

build客户端。启动服务器,运行两次客户端程序,就可以两个客户端互相通信了
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值