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

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 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)
  • ¥15 Windows11, backspace, enter, space键失灵