level 4
c#写的一个tcp服务器接收机器人数据,在vs里编译使用接收数据没问题,但是将实现功能函数放到unity中启动为什么传输不了,可以查到服务端监听已经打开了但是客户端那边连接不上。
2024年01月23日 13点01分
1
level 4
public KUKA_TCP_Server()
{
Client = new Socket[256];
theListClient = new string[256,2];
_sessionTable = new Hashtable(53);
}
private void OpenTCP()
{
ThreadStart TCPDelegate = new ThreadStart(TCPListen); //新建一个委托线程
tcpDelegate = new Thread(TCPDelegate); //实例化新线程
tcpDelegate.Start();
}
/// <summary>
/// 创建TCPServer并监听
/// </summary>
public void TCPListen()
{
var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //初始化 Socket 实例,该 Socket 只用于绑定本地终结点并接受客户端连接
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); //允许 Socket 被绑定在已使用的地址上
try
{
localEP = new IPEndPoint(IPAddress.Parse(ipaddress), setPort); //初始化本地终结点实例
listener.Bind(localEP); //绑定
listener.Listen(10); //监听
Print("开始监听");
listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener); //开始接受异步连接
/**
* BeginAccept 方法的第二个参数(object state)是一个用户定义的对象,它可以传递给回调函数,该参数可以用于在回调函数中传递额外的信息。
* 比如我们将监听 Socket 对象作为 state 参数传递给了 BeginAccept 方法,在 BeginAccept 方法中,它会使用监听 Socket 对象去初始化一个 IAsyncResult 对象并返回。
* IAsyncResult 对象包含了一个 AsyncState 属性,它的值就是传递给 BeginAccept 方法的第二个参数 state。这样,我们就能够在回调函数中使用该属性来获取监听 Socket 对象,以便继续监听客户端连接。
* 当然,可以根据需要传递任何类型的对象作为 state 参数。这个参数对于在回调函数中传递额外的信息非常有用。
*/
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 客户端连接
/// </summary>
/// <param name="ar">异步操作的结果</param>
public void OnConnectRequest(IAsyncResult ar)
{
var listener = (Socket)ar.AsyncState; //在回调函数中获取监听 Socket 对象以便继续监听客户端连接
Client[theIndex] = listener.EndAccept(ar); //结束异步接受操作。该方法会返回一个新的 Socket,新的 Socket 对象才是用于与客户端进行通信的
byte[] byteDateLine = new byte[65536]; //创建一个 64KB 的接收数据缓冲区
var remote = Client[theIndex].RemoteEndPoint; //RemoteEndPoint:IP + Port;e.g. 127.0.0.1:55991
_sessionTable.Add(remote, null); //把连接成功的客户端的 RemoteEndPoint 实例放入哈希表(作为键存储,所有键的值为null)
Print($"客户端[{Client[theIndex].RemoteEndPoint}]连接成功!");
theListClient[theIndex,0] = Client[theIndex].RemoteEndPoint.ToString(); //二维数组第一列放 RemoteEndPoint
theListClient[theIndex,1] = "1"; //二维数组第二列放 RemoteEndPoint 状态:"1"表示当前远端终结点为激活状态;"0"表示为失效状态
listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener); //继续监听等待新的客户端连接
theIndex++; //索引+1
int myIndex = theIndex - 1; //获取当前连接的 Socket 索引
while (true) //进入死循环持续接收来自客户端的消息
{
try
{
if (theListClient[myIndex,1] == "0")
return;
Thread.Sleep(150);
int recv = Client[myIndex].Receive(byteDateLine);
string stringdata = Encoding.UTF8.GetString(byteDateLine, 0, recv);
string ip = Client[myIndex].RemoteEndPoint.ToString();
if (stringdata.Any()) //接受到客户端消息
{
Print($"收到来自[{ip}]消息:" + stringdata);
}
else
{
Print($"客户端[{ip}]已断开连接!");
break;
}
}
catch (SocketException e)
{
string ip = Client[myIndex].RemoteEndPoint.ToString(); //从列表中移除通讯失败的客户端
_sessionTable.Remove(Client[myIndex].RemoteEndPoint);
for (int i = 0; i < 256; i++)
{
if (Client[myIndex].RemoteEndPoint.ToString() == theListClient[i,0])
theListClient[i,1] = "0";
}
Print($"{e.Message}客户端[{ip}]断开了连接!");
break;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
break;
}
}
}
功能代码就这么多,unity中在start函数里调用public KUKA_TCP_Server(),最后加了个关闭线程代码
2024年01月24日 07点01分
4
start()里面还调用了OpenTCP()
2024年01月24日 07点01分
@给你一棍😳 start需要继承monobehaviour才能运行,而monobehaviour不支持构造函数,所以你这个脚本矛盾挺多的
2024年01月29日 10点01分