Unity中c#为客户端,c++为服务器端进行socket通信


Unity中c#为客户端,c++为服务器端进行socket通信
1.需求

最近在项目中,要求将unity中虚拟相机的坐标变化等信息用socket传入c++写的处理程序中。相当于用C#写客户端,c++写服务器端。主要参考了一下博客:http://blog.csdn.net/qq_34204419/article/details/82529386

2.注意C#与C++数据类型的对应关系

Unity中c#为客户端,c++为服务器端进行socket通信数据类型不对应,编码方式不一致都可能导致传输结果为乱码。
大佬分别写了一个C#类和c++结构体进行对齐。
c#:

[Serializable] //序列化对象
[StructLayout(LayoutKind.Sequential, Pack = 1)] // 按1字节对齐
public class UserMsg
{
public int messageID;
public int clientID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 200)] //限制200字节
public byte[] message;
}

c++:

typedef struct
{
int messageID;
int clientID;
char message[200];
}UserMsg;

3.code

我对大佬代码进行了一点改变,符合我的需求。

Unity,c#,客户端

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
using System.Runtime.InteropServices;

[Serializable]
[StructLayout(LayoutKind.Sequential,Pack=1)]
public class UserMsg
{
//public int messageID;
//public int clientID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 50)] //限制50字节
public byte[] message;
}

public class Sockets : MonoBehaviour {
Socket socketsend;
public GameObject cube=null;
// List<byte> list = new List<byte>();
// Use this for initialization\
public static byte[] StructToBytes(object obj)
{
//得到结构体的大小
int size = Marshal.SizeOf(obj);
//创建byte数组
byte[] bytes = new byte[size];
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将结构体拷到分配好的内存空间
Marshal.StructureToPtr(obj, structPtr, false);
//从内存空间拷到byte数组
Marshal.Copy(structPtr, bytes, 0, size);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回byte数组
return bytes;
}

void Start ()
{
try
{
socketsend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse("127.0.0.1");
IPEndPoint point = new IPEndPoint(ip, 50000);
socketsend.Connect(point);
Debug.Log("连接成功!");
//开启线程接收消息
Thread th = new Thread(Recieve);
th.IsBackground = true;
th.Start();
}
catch
{

Debug.Log("初始化错误");
}
}

private void OnGUI()
{
if (GUILayout.Button("结束"))
{
socketsend.Close();

}
}

// Update is called once per frame
void Update ()
{
try
{
if (socketsend.Connected)
{

string strCube_x = cube.transform.position.x.ToString();
string strCube_y = cube.transform.position.y.ToString();
string strCube_z = cube.transform.position.z.ToString();
Debug.Log(strCube_x);
string str_Position = strCube_x + "a" + strCube_y + "b" + strCube_z;
//Debug.Log("12"+str_Position);
UserMsg ux = new UserMsg();

ux.message = Encoding.ASCII.GetBytes(str_Position);

byte[] message_x = StructToBytes(ux);

socketsend.Send(message_x);

}
else
{
Debug.Log("发送结束!");
}

}
catch(SocketException se)
{
Debug.Log("发送失败!");
}

}

//
void Recieve()
{
while (true)
{
try
{
byte[] buffer = new byte[1024 * 1024 * 3];
int r = socketsend.Receive(buffer);
if (r == 0)
{
break;
Environment.Exit(0);//结束当前进程

}
string str = Encoding.UTF8.GetString(buffer, 0, r);
Debug.Log("receive:" + str);
}
catch { }
}
}
}


c++,服务器端

#include <WinSock2.h>
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <thread>
#pragma comment(lib,"WS2_32.lib")

using namespace std;

//全局常量
const int BUF_SIZE = 50;
int flag = 1;
int flag1 = 1;
char inputC = 0;
char str1[] = "a";
char str2[] = "b";

//全局变量
SOCKET sockSer, sockCli;
SOCKADDR_IN addrSer, addrCli;
int naddr = sizeof(SOCKADDR_IN);
int retValx;
double cube_x ;
double cube_y ;
double cube_z ;
int w ;
int e ;
int tx ,ty;

char sendbuf[BUF_SIZE];
char inputbuf[BUF_SIZE];

//函数声明
typedef struct
{
char message[50];
}UserMsg;

void posReceive()
{
while (true) {
//ZeroMemory(recebuf, BUF_SIZE);
char recebuf_x[BUF_SIZE];

UserMsg u_x;

retValx= recv(sockCli, recebuf_x, BUF_SIZE, 0);
// cout << retValx << endl;

if (retValx<=0)
{
cout << " recv failed" << endl;
break;
}

u_x = *(UserMsg*)recebuf_x;

w = 0;
e = 0;
tx= 0;
ty= 0;

for (int i = 0; i < retValx; i++)
{

if (u_x.message[i] == str1[0] )
{
char message_x[50];
tx = i;
for (int j = 0; j < tx; j++)
{
message_x[j] = u_x.message[j];
}
cube_x = strtod(message_x, NULL);
}
if (u_x.message[i] == str2[0] )
{
ty = i;
char message_y[50];
char message_z[50];
for (int j = tx+1; j < ty; j++)
{
message_y[w] = u_x.message[j];
w++;
}
cube_y = strtod(message_y, NULL);
for (int j = ty+1; j < retValx; j++)
{
message_z[e] = u_x.message[j];
e++;
}
cube_z = strtod(message_z, NULL);
break;
}
}

cout << cube_x << ","<<cube_y<<","<<cube_z<<endl;

}
}

int main()
{

WSADATA wsdata;
if (WSAStartup(MAKEWORD(2, 2), &wsdata) != 0)
{
//输出出错信息
cout << "载入socket库出错!" << endl;
system("pause");
}

//创建Socket
sockSer = socket(AF_INET, SOCK_STREAM, 0);
//初始化地址
addrSer.sin_port = htons(50000);
addrSer.sin_family = AF_INET;
addrSer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

//绑定Socket
bind(sockSer, (SOCKADDR*)&addrSer, sizeof(SOCKADDR));
cout << "bind success!" << endl;

while (flag)
{
//监听
listen(sockSer, 2);
//接受连接请求
sockCli=accept(sockSer,(SOCKADDR*)&addrCli,&naddr);
if (sockCli != INVALID_SOCKET) {
cout << "连接成功!" << endl;
strcpy_s(sendbuf, "hello!");
send(sockCli,sendbuf,sizeof(sendbuf),0);
thread t1(posReceive);
t1.join();
flag = 0;

}
}
while (flag1)
{
if (inputC == 27)
{
closesocket(sockSer);
closesocket(sockCli);
WSACleanup();
flag1 = 0;
}
}

return 0;
}

4. 主要思想

将相机的每一帧的位置进行发送:

                string strCube_x = cube.transform.position.x.ToString();
string strCube_y = cube.transform.position.y.ToString();
string strCube_z = cube.transform.position.z.ToString();

主要为x,y,z的坐标。将他们变为一个str类型进行发送。因为主要为数字,在xyzz坐标中加入字母进行区分。在服务端在进行遍历,分解。

5.结果
Unity

Unity中c#为客户端,c++为服务器端进行socket通信Unity中c#为客户端,c++为服务器端进行socket通信

c++端

Unity中c#为客户端,c++为服务器端进行socket通信Unity中c#为客户端,c++为服务器端进行socket通信欢迎大佬批评指正。

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

Unity中c#为客户端,c++为服务器端进行socket通信

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » Unity中c#为客户端,c++为服务器端进行socket通信
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏