unity应用之socket连接–步骤三同一工程中运行

unity应用之socket连接–步骤三同一工程中运行

将服务端和客户端都在unity中实现。

注意:服务端需要等待,即包含阻塞方法,unity中所有方法都是一个主线程中运行,所以,如果以如果直接在start中调用启动服务器的方法,unity会直接卡死的,所以我们就自己起一个线程去搞服务端部分。
unity中起线程后要清楚两点:
1、monoBehavior类中的方法尽量别用了,会出现不可预知的bug。
2、自己起的线程,系统不会掺和,自己找个合适的地方再把他kill掉。
下面的代码是在程序结束时杀掉线程,起线程就像拉屎,完事一定要记得自己擦,系统不会给你擦,经测试不擦第二次启动unity会无响应。

简单实现了从客户端发送一个字符串的包到服务端,服务端接收后并打印出来,代码全部贴出来:

在同一个unity工程中,新建两个脚本,一个是服务端,一个是客户端,均须挂在到场景中的空物体上,不然连接不上。

客户端代码:

using UnityEngine;
using System.Collections;

using System.Net;
using System.Net.Sockets;
using System;
using System.Text;

public class SocketClient : MonoBehaviour
{

    void Start()
    {

    }

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha1))
        {
            Client();
        }
       
    }
    TcpClient client;
    private void Client()
    {
        client = new TcpClient();
        try
        {
            client.Connect(IPAddress.Parse("192.168.1.104"), 10001);//同步方法,连接成功、抛出异常、服务器不存在等之前程序会被阻塞
        }
        catch (Exception ex)
        {
            Debug.Log("客户端连接异常:" + ex.Message);
        }
        Debug.Log("LocalEndPoint = " + client.Client.LocalEndPoint + ". RemoteEndPoint = " + client.Client.RemoteEndPoint);

        //客户端发送数据部分
        for (int i = 0; i < 2; i++)
        {
            try
            {
                string msg = "hello server i am No " + i;
                NetworkStream streamToServer = client.GetStream();//获得客户端的流
                byte[] buffer = Encoding.Unicode.GetBytes(msg);//将字符串转化为二进制
                streamToServer.Write(buffer, 0, buffer.Length);//将转换好的二进制数据写入流中并发送
                Debug.Log("发出消息:" + msg);
            }
            catch (Exception ex)
            {
                Debug.Log("服务端产生异常:" + ex.Message);
            }
        }
    }

}

服务端代码块:

using UnityEngine;
using System.Collections;

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
/// <summary>
/// scoket服务器监听端口脚本
/// </summary>
public class SocketServer : MonoBehaviour
{

    private Thread thStartServer;//定义启动socket的线程
    void Start()
    {
        thStartServer = new Thread(StartServer);
        thStartServer.Start();//启动该线程
        //thStartServer = new Thread(OnApplicationQuit);
        //thStartServer.Start();
    }

    void Update()
    {
    }

    private void StartServer()
    {
        const int bufferSize = 8792;//缓存大小,8192字节
        IPAddress ip = IPAddress.Parse("192.168.1.104");

        TcpListener tlistener = new TcpListener(ip, 10001);
        tlistener.Start();
        Console.WriteLine("Socket服务器监听启动......");

        TcpClient remoteClient = tlistener.AcceptTcpClient();//接收已连接的客户端,阻塞方法
        Debug.Log("客户端已连接!local:" + remoteClient.Client.LocalEndPoint + "<---Client:" + remoteClient.Client.RemoteEndPoint);
        NetworkStream streamToClient = remoteClient.GetStream();//获得来自客户端的流
        do
        {
            try  //直接关掉客户端,服务器端会抛出异常
            {
                //接收客户端发送的数据部分
                byte[] buffer = new byte[bufferSize];//定义一个缓存buffer数组
                int byteRead = streamToClient.Read(buffer, 0, bufferSize);//将数据搞入缓存中(有朋友说read()是阻塞方法,测试中未发现程序阻塞)
                if (byteRead == 0)//连接断开,或者在TCPClient上调用了Close()方法,或者在流上调用了Dispose()方法。
                {
                    Debug.Log("客户端连接断开......");
                    break;
                }

                string msg = Encoding.Unicode.GetString(buffer, 0, byteRead);//从二进制转换为字符串对应的客户端会有从字符串转换为二进制的方法
                Debug.Log("接收数据:" + msg + ".数据长度:[" + byteRead + "byte]");
            }
            catch (Exception ex)
            {
                Debug.Log("客户端异常:" + ex.Message);
                break;
            }
        }
        while (true);
    }

    void OnApplicationQuit()
    {
        thStartServer.Abort();//在程序结束时杀掉线程,想起以前老谢给我讲的,起线程就像拉屎,完事一定要记得自己擦,系统不会给你擦,经测试不擦第二次启动unity会无响应
    }


}

结果

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值