unity网络

网络实现资源共享和信息传递,

ip地址识别机器,端口进行通信。

TCP(三次握手,确定连接双方的序列号(seq)和确认号(ack))必须双方建立连接。UDP不需要

数据不一定能确认接收方接收,会等待接收方回应。

套接字是支持TCP/IP协议网络通信的基本操作单元。

同步socket

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace sever
{
    class Program
    {
        //指定套接字信息
        static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        static void Main(string[] args)
        {
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            IPEndPoint iPEnd = new IPEndPoint(ip, 8888);
            socket.Bind(iPEnd);
            socket.Listen(0);//backlog指定队列中最多连接数。
            Console.WriteLine("服务端启动");
            while (true)
            {
               Socket conn= socket.Accept();
                byte[] b = new byte[1024];
                int count = conn.Receive(b);
                string msg = Encoding.Unicode.GetString(b);
                Console.WriteLine("收到客户端 {0} 消息:{1}",conn.LocalEndPoint,msg);

                byte[] re = Encoding.Unicode.GetBytes("响应客户:"+System.DateTime.Now.ToString());
                conn.Send(re);
            }
        }
    }
}
using UnityEngine;
using UnityEngine.UI;
using System.Net.Sockets;
using System.Text;

public class ClientWork : MonoBehaviour
{
    public InputField ip, port;
    public Button conn;
    public Text clienInfo;
    public Text msg;
   
    public void connServer()
    {
        Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        socket.Connect(ip.text, int.Parse(port.text));

        clienInfo.text = socket.LocalEndPoint.ToString();

        socket.Send(Encoding.Unicode.GetBytes("hello server"));

        byte[] b = new byte[1024];
        socket.Receive(b);
        msg.text = Encoding.Unicode.GetString(b);
    }
}

异步模式下,服务端使用BeginAccept和EndAccept方法。

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

public class Serv
{
    //监听嵌套字
    public Socket listenfd;
    //客户端链接
    public Conn[] conns;
    //最大链接数
    public int maxConn = 50;

    //获取链接池索引,返回负数表示获取失败
    public int NewIndex()
    {
        if (conns == null)
            return -1;
        for (int i = 0; i < conns.Length; i++)
        {
            if (conns[i] == null)
            {
                conns[i] = new Conn();
                return i;
            }
            else if (conns[i].isUse == false)
            {
                return i;
            }
        }
        return -1;
    }

    //开启服务器
    public void Start(string host, int port)
    {
        //链接池
        conns = new Conn[maxConn];
        for (int i = 0; i < maxConn; i++)
        {
            conns[i] = new Conn();
        }
        //Socket
        listenfd = new Socket(AddressFamily.InterNetwork,
                              SocketType.Stream, ProtocolType.Tcp);
        //Bind
        IPAddress ipAdr = IPAddress.Parse(host);
        IPEndPoint ipEp = new IPEndPoint(ipAdr, port);
        listenfd.Bind(ipEp);
        //Listen
        listenfd.Listen(maxConn);
        //Accept
        listenfd.BeginAccept(AcceptCb, null);
        Console.WriteLine("[服务器]启动成功");
    }


    //Accept回调
    private void AcceptCb(IAsyncResult ar)
    {
        try
        {
            Socket socket = listenfd.EndAccept(ar);
            int index = NewIndex();

            if (index < 0)
            {
                socket.Close();
                Console.Write("[警告]链接已满");
            }
            else
            {
                Conn conn = conns[index];
                conn.Init(socket);
                string adr = conn.GetAdress();
                Console.WriteLine("客户端连接 [" + adr + "] conn池ID:" + index);
                conn.socket.BeginReceive(conn.readBuff,
                                         conn.buffCount, conn.BuffRemain(),
                                         SocketFlags.None, ReceiveCb, conn);
            }
            listenfd.BeginAccept(AcceptCb, null);
        }
        catch (Exception e)
        {
            Console.WriteLine("AcceptCb失败:" + e.Message);
        }
    }

    private void ReceiveCb(IAsyncResult ar)
    {
        Conn conn = (Conn)ar.AsyncState;
        try
        {
            int count = conn.socket.EndReceive(ar);
            //关闭信号
            if (count <= 0)
            {
                Console.WriteLine("收到 [" + conn.GetAdress() + "] 断开链接");
                conn.Close();
                return;
            }
            //数据处理
            string str = System.Text.Encoding.UTF8.GetString(conn.readBuff, 0, count);
            Console.WriteLine("收到 [" + conn.GetAdress() + "] 数据:" + str);
            str = conn.GetAdress() + ":" + str;
            byte[] bytes = System.Text.Encoding.Default.GetBytes(str);
            //广播
            for (int i = 0; i < conns.Length; i++)
            {
                if (conns[i] == null)
                    continue;
                if (!conns[i].isUse)
                    continue;
                Console.WriteLine("将消息转播给 " + conns[i].GetAdress());
                conns[i].socket.Send(bytes);
            }
            //继续接收	
            conn.socket.BeginReceive(conn.readBuff,
                                     conn.buffCount, conn.BuffRemain(),
                                     SocketFlags.None, ReceiveCb, conn);
        }
        catch (Exception e)
        {
            Console.WriteLine("收到 [" + conn.GetAdress() + "] 断开链接");
            conn.Close();
        }
    }
}

using UnityEngine;
using UnityEngine.UI;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System;
public class ClientWork : MonoBehaviour
{
    //服务器IP和端口
    public InputField hostInput;
    public InputField portInput;
    //显示客户端收到的消息
    public Text recvText;
    public string recvStr;
    //显示客户端IP和端口
    public Text clientText;
    //聊天输入框
    public InputField textInput;
    //Socket和接收缓冲区
    Socket socket;
    const int BUFFER_SIZE = 1024;
    public byte[] readBuff = new byte[BUFFER_SIZE];

    //因为只有主线程能够修改UI组件属性
    //因此在Update里更换文本
    void Update()
    {
        recvText.text = recvStr;
    }

    //连接
    public void Connetion()
    {
        if (null != socket) return;
        //清理text
        recvText.text = "";
        //Socket
        socket = new Socket(AddressFamily.InterNetwork,
                         SocketType.Stream, ProtocolType.Tcp);
        //Connect
        string host = hostInput.text;
        int port = int.Parse(portInput.text);
        socket.Connect(host, port);
        clientText.text = socket.LocalEndPoint.ToString();
        //Recv
        socket.BeginReceive(readBuff, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null);
    }

    //接收回调
    private void ReceiveCb(IAsyncResult ar)
    {
        try
        {
            //count是接收数据的大小
            int count = socket.EndReceive(ar);
            //数据处理
            string str = Encoding.UTF8.GetString(readBuff, 0, count);
            if (recvStr.Length > 300) recvStr = "";
            recvStr += str + "\n";
            //继续接收	
            socket.BeginReceive(readBuff, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCb, null);
        }
        catch 
        {
            recvText.text += "链接已断开";
            socket.Close();
        }
    }

    //发送数据
    public void Send()
    {
        string str = textInput.text;
        byte[] bytes = Encoding.UTF8.GetBytes(str);
        try
        {
            socket.Send(bytes);
        }
        catch { }
    }
}

238

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值