目前使用史陶比尔的c# soap当作server端,unity为client端,目前想要丢6个关节变数到unity,之后再分别丢到相对应的关节中,但本人机械专业,对程式不太了解,求指导。
下面是史陶比尔c# soap的程式码(server):
private void button55_Click_1(object sender, EventArgs e)
{
double c_px = 311.2;
double c_py = 18.38;
double c_pz = 137.44;
double c_rx = 10;
double c_ry = 179.93;
double c_rz = 11.53;
//創建服務器
Socket severSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//ip地址和端口號綁定
EndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10001);
//綁定服務器
severSocket.Bind(endPoint);
//發起監聽
severSocket.Listen(1000);
Console.WriteLine("server already opened!");
Console.WriteLine("Waiting for Client connect!");
Socket cilentSocket = severSocket.Accept();//這裡會阻塞,等待鏈接
Console.WriteLine("client is connect.");
while (true)
{
byte[] sendMsg = System.Text.Encoding.UTF8.GetBytes(string.Format(c_px.ToString())+',');
byte[] sendMsg2 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_py.ToString())+',');
byte[] sendMsg3 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_pz.ToString())+',');
byte[] sendMsg4 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_rx.ToString())+',');
byte[] sendMsg5 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_ry.ToString())+',');
byte[] sendMsg6 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_rz.ToString()));
int sendLength = cilentSocket.Send(sendMsg, SocketFlags.None);
int sendLength2 = cilentSocket.Send(sendMsg2, SocketFlags.None);
int sendLength3 = cilentSocket.Send(sendMsg3, SocketFlags.None);
int sendLength4 = cilentSocket.Send(sendMsg4, SocketFlags.None);
int sendLength5 = cilentSocket.Send(sendMsg5, SocketFlags.None);
int sendLength6 = cilentSocket.Send(sendMsg6, SocketFlags.None);}
}
有什么方法可以把上面的c_px, c_py, c_pz, c_rx, c_ry, c_rz的变成一个byte array并用tcp socket的方式传到unity? 我目前是一个一个传到unity。
感谢各位,顺便附上我的client程式码(我也是参考别的博主的)。
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.Net;
using System;
using System.Collections.Generic;
using System.Linq;
/// <summary>
/// 客戶端的控制腳本
/// </summary>
public class ClientSocketController : MonoBehaviour
{
/// <summary>
/// 鏈接對象
/// </summary>
public Socket clientSocket;
/// <summary>
/// ip地址
/// </summary>
public string ipAddress = "127.0.0.1";
/// <summary>
/// 端口號,這個是服務器開設的端口號
/// </summary>
public int portNumber = 10001;
/// <summary>
/// 鏈接間隔時間
/// </summary>
public float connectInterval = 1;
/// <summary>
/// 當前鏈接時間
/// </summary>
public float connectTime = 0;
/// <summary>
/// 鏈接次數
/// </summary>
public int connectCount = 0;
/// <summary>
/// 是否在連接中
/// </summary>
public bool isConnecting = false;
void Start()
{
//調用開始連接
ConnectedToServer();
}
/// <summary>
/// 鏈接到服務器
/// </summary>
public void ConnectedToServer()
{
//鏈接次數增加
connectCount++;
isConnecting = true;
Debug.Log("這是第" + connectCount + "次連接");
//如果客戶端不為空
if (clientSocket != null)
{
try
{
//斷開連接,釋放資源
clientSocket.Disconnect(false);
clientSocket.Close();
}
catch (System.Exception e)
{
Debug.Log(e.ToString());
}
}
//創建新的鏈接(固定格式)
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//設置端口號和ip地址
EndPoint endPoint = new IPEndPoint(IPAddress.Parse(ipAddress), portNumber);
//發起鏈接
clientSocket.BeginConnect(endPoint, OnConnectCallBack, "");
}
/// <summary>
/// 開始鏈接的回調
/// </summary>
/// <param name="ar"></param>
public void OnConnectCallBack(IAsyncResult ar)
{
Debug.Log("連接完成!!!!");
if (clientSocket.Connected)
{
//鏈接成功
Debug.Log("連接成功");
connectCount = 0;
//開啟收消息
ReceiveFormServer();
}
else
{
//鏈接失敗
Debug.Log("連接失敗");
//計時重置
connectTime = 0;
}
isConnecting = false;
//結束鏈接
clientSocket.EndConnect(ar);
}
/// <summary>
/// 向服務器發送字符串信息
/// </summary>
/// <param name="msg"></param>
public void SendMessageToServer(string msg)
{
//將字符串轉成byte數組
byte[] msgBytes = System.Text.Encoding.UTF8.GetBytes(msg);
clientSocket.BeginSend(msgBytes, 0, msgBytes.Length, SocketFlags.None, SendMassageCallBack, 1);
}
/// <summary>
/// 發送信息的回調
/// </summary>
/// <param name="ar"></param>
public void SendMassageCallBack(IAsyncResult ar)
{
//關閉消息發送
int length = clientSocket.EndSend(ar);
Debug.Log("信息發送成功,發送的信息長度是:" + length);
}
/// <summary>
/// 從服務器接收消息
/// </summary>
public void ReceiveFormServer()
{
//定義緩衝池
byte[] buffer = new byte[512];
clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveFormServerCallBack, buffer);
}
/// <summary>
/// 信息接收方法的回調
/// </summary>
/// <param name="ar"></param>
public void ReceiveFormServerCallBack(IAsyncResult ar)
{
//結束接收
int length = clientSocket.EndReceive(ar);
byte[] buffer = (byte[])ar.AsyncState;
//將接收的東西轉為字符串
string msg = System.Text.Encoding.UTF8.GetString(buffer, 0, length);
//Debug.Log(msg); //接收到的消息是 //"接收到的消息是"+
//開啟下一次接收消息
ReceiveFormServer();
string robottarget = Convert.ToString(msg);
robottarget = string.Join("", robottarget.Split());
List<string> r_robottarget = robottarget.Split(',').ToList();
//Debug.Log(robottarget);
Debug.Log(r_robottarget);
}
void Update()
{
if (Input.GetMouseButton(0))
{
SendMessageToServer("哭阿!");
}
if (clientSocket != null && clientSocket.Connected == false)
{
//鏈接沒有成功
//計時
connectTime += Time.deltaTime;
if (connectTime > connectInterval && isConnecting == false)//如果時間大於鏈接重置時間間隔且沒有鏈接
{
if (connectCount >= 7)
{
Debug.Log("已經嘗試了7次,請檢查網絡連接");
clientSocket = null;
}
else
{
//重連一次
ConnectedToServer();
}
}
}
}
private void OnDestroy()
{
Debug.Log("物體被銷毀");
//關閉客戶端
clientSocket.Close();
}
}
服务端和客户端封装一个相同的数据结构JointData
using System;
/// <summary>
/// 关节数据
/// </summary>
[Serializable]
public class JointData
{
public double c_px;
public double c_py;
public double c_pz;
public double c_rx;
public double c_ry;
public double c_rz;
public JointData(double c_px, double c_py, double c_pz, double c_rx, double c_ry, double c_rz)
{
this.c_px = c_px;
this.c_py = c_py;
this.c_pz = c_pz;
this.c_rx = c_rx;
this.c_ry = c_ry;
this.c_rz = c_rz;
}
}
使用一个序列化与反序列化工具,建议使用NewtonsoftJson,因为你这使用了双精度浮点数。
服务端发送数据时New一个JointData类,使用构造函数将数据传入,然后将其序列化为字符串再发送
JointData jointData = new JointData(311.2, 18.38, 137.44, 10, 179.93, 11.53);
string data = JsonConvert.SerializeObject(jointData);
客户端接收到data字符串数据后,将其反序列化为JointData类
using UnityEngine;
using Newtonsoft.Json;
public class Example : MonoBehaviour
{
private void Start()
{
//接收到的数据
string data = "";
//反序列化
JointData jointData = JsonConvert.DeserializeObject<JointData>(data);
}
}
反序列化后,jointData里包含各个关节数据,拿去赋值就可以了。
方法很多,你可以把6个数据封装成一个Json然后转成byte数组发送给客户端,或者你把6个现有的byte数组,直接组合到一起发送客户端,然后按照你发送的格式在客户端解析就可以了。
byte[] sendMsg = System.Text.Encoding.UTF8.GetBytes(string.Format(c_px.ToString())+',');
byte[] sendMsg2 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_py.ToString())+',');
byte[] sendMsg3 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_pz.ToString())+',');
byte[] sendMsg4 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_rx.ToString())+',');
byte[] sendMsg5 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_ry.ToString())+',');
byte[] sendMsg6 = System.Text.Encoding.UTF8.GetBytes(string.Format(c_rz.ToString()));
这就是说你把他当字符串传递过去的,我也不介绍啥json了,直接给你最简单的玩意
string str=$"{c_px},{c_py},{c_pz},{c_rx},{c_ry},{ c_rz}"
byte[] sendMsg = System.Text.Encoding.UTF8.GetBytes(str);
顺带多提一句:作为机械专业的,不是更应该用ROS做基准开发框架了,那个才是专门对机械专业的设计的东西(完全忽略你们不需要掌握的技术,所有硬件都是Node节点,所有通讯皆为像bus总线发消息)
Ros#的简单介绍
https://cloud.tencent.com/developer/article/1990372