斗斗金 2022-09-07 10:47 采纳率: 50%
浏览 92
已结题

unity socket 异步通信

客户端 和服务端 可以链接成功,并且客户端按空格可以发送消息给服务端,但是问题出现在 服务端发送消息 客户端收不到
实在不知道什么地方错误了
就服务端发送空格消息过不去
客户端


using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Collections.Generic;
public class ClientState
{
    public Socket socket;
    public byte[] data = new byte[1024];
}
public class Server : MonoBehaviour
{
    private Socket server;
    EndPoint clientEnd = new IPEndPoint(IPAddress.Any, 0);   //实例化一个客户端端口 来给客户端发消息
    private Dictionary<Socket, ClientState> clients = new Dictionary<Socket, ClientState>();
    void Start()
    {
        server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //开启服务
        IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888); //建立端口
        server.Bind(endPoint); //绑定端口 IP
        server.Listen(0);//监听客户端数量不限  
        Debug.Log("服务端启动成功:等待客户端连");
        server.BeginAccept(AcceptCallBack, server);  //开启异步监听接入
    }
    void AcceptCallBack(IAsyncResult ar)
    {
        Debug.Log("客户端接入成功:等待发送消息");
        Socket server = ar.AsyncState as Socket;  //状态结果
        Socket client = server.EndAccept(ar); //   接受结果  //返回这个通道

        Debug.Log($"{server.LocalEndPoint}---{client.RemoteEndPoint}");
        clientEnd = client.RemoteEndPoint;

        //下面3条是给字典赋值保存 这些人正在连接中
        ClientState clientState = new ClientState();  //实例化了一个客户端 数据
        clientState.socket = client;//客户数据的  socket复制
        clients.Add(client, clientState); //把客户的ip和端口保存起来


        //接收此客户端发来的信息
        //client.BeginReceive(clientState.data, 0, 1024, 0, ReceiveCallBack, clientState);  
        //继续监听新的客户端接入
        server.BeginAccept(AcceptCallBack, server); //进入无限循环监听
    }
    void ReceiveCallBack(IAsyncResult ar)
    {
        ClientState state = ar.AsyncState as ClientState;  //获取正在工作的socket
        Socket client = state.socket; //获取到这个socket
        int count = client.EndReceive(ar); //接受数据字符串
        if (count == 0)
        {
            client.Close();
            clients.Remove(client); //从保存的字典中删除 
            Debug.Log("客户端关闭");
            return;
        }
        string msg = Encoding.UTF8.GetString(state.data, 0, count);
        Debug.Log("收到客户端消息:" + msg);
        client.BeginReceive(state.data, 0, 1024, 0, ReceiveCallBack, state);
    }
    public void SendToServer(string sendStr)
    {
        byte[] sendData = new byte[1024]; //发送的数据,必须为字节
        sendData = Encoding.ASCII.GetBytes(sendStr);

        //创建发送参数
        SocketAsyncEventArgs sendEventArgs = new SocketAsyncEventArgs();
        sendEventArgs.RemoteEndPoint = clientEnd;
        //设置要发送的数据
        sendEventArgs.SetBuffer(sendData, 0, sendData.Length);
    }

    void Update()
    {

        if (Input.GetKeyDown(KeyCode.Space))
        {
            //按下空格向服务器发送消息
            SendToServer("ceshi");
        }
    }

}

服务端

using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
public class Client : MonoBehaviour
{
    private Socket client;
    private byte[] data = new byte[1024];
    IPEndPoint endPoint;
    // Use this for initialization
    void Start()
    {
        client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        //ip:"127.0.0.1"连接本地测试, 端口号:8888 服务器客户端端口号需相同
        endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
        client.BeginConnect(endPoint, OnConnectCallBack, client);
    }
    void OnConnectCallBack(IAsyncResult ar)
    {
        Socket socket = ar.AsyncState as Socket;
        socket.EndConnect(ar);
        Debug.Log("Connected sucess");
        socket.BeginReceive(data, 0, 1024, 0, OnReiceiveCallBack, socket);

    }
    void OnReiceiveCallBack(IAsyncResult ar)
    {
        Debug.Log("111");
        Socket socket = ar.AsyncState as Socket;
        int count = socket.EndReceive(ar);
        string recStr = Encoding.UTF8.GetString(data, 0, count);
        Debug.Log("收到服务器发送消息:" + recStr);
        //在此处继续接收信息
        socket.BeginReceive(data, 0, 1024, 0, OnReiceiveCallBack, socket);
    }

    public void SendToServer(string sendStr)
    {
        byte[] sendData = new byte[1024]; //发送的数据,必须为字节
        sendData = Encoding.ASCII.GetBytes(sendStr);

        //创建发送参数
        SocketAsyncEventArgs sendEventArgs = new SocketAsyncEventArgs();
        sendEventArgs.RemoteEndPoint = endPoint;
        //设置要发送的数据
        sendEventArgs.SetBuffer(sendData, 0, sendData.Length);
        //异步发送数据
        client.SendAsync(sendEventArgs);

    }
    void Update()
    {

        if (Input.GetKeyDown(KeyCode.Space))
        {
            //按下空格向服务器发送消息
            SendToServer("ceshi");
        }
    }
}

  • 写回答

3条回答 默认 最新

  • 於黾 2022-09-07 10:59
    关注

    你搞错对象了呀
    client是用来侦听的
    socket 才是建立好的通信啊
    可是你的socket 是个局部变量

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月9日
  • 已采纳回答 9月7日
  • 创建了问题 9月7日

悬赏问题

  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置