我已经设法设置好了,这样我的unity应用程序就可以接收tcp数据了。但是,当我运行该项目时,整个应用程序冻结,并且在收到消息之前不会执行任何操作。然后,一旦收到一条消息,它就会将该消息打印出来,并且不允许我的客户端再次连接到它。
这段代码是我的TCP阅读类的全部,是不是我在这里做了什么愚蠢的事情导致了这种情况?
有没有更好的读入TCP数据的方法?
using UnityEngine;
using System.Collections;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System;
using System.IO;
public class TCPConnection: MonoBehaviour
{
public string ip_address = "";
public int port_number = 0;
void Start()
{
try
{
IPAddress ipAddress = IPAddress.Parse(ip_address);
TcpListener listener = new TcpListener(ipAddress, port_number);
listener.Start();
print("The server is running at port " + port_number);
print("The local end point is :" + listener.LocalEndpoint);
print("Waiting for connection.....");
Socket socket = listener.AcceptSocket();
print("Connection accepted from " + socket.RemoteEndPoint);
byte[] b = new byte[100];
int k = socket.Receive(b);
print("recieved...");
for (int i = 0; i < k; i++)
print (Convert.ToChar(b[i]));
ASCIIEncoding ascii = new ASCIIEncoding();
socket.Send(ascii.GetBytes("The string was recieved by the server"));
print("\nSent ack");
}
catch (Exception e)
{
print("error...." + e.Message);
}
}
}发布于 2013-09-27 02:27:20
listener.AcceptSocket和socket.Receive是阻塞调用。所以你的UI冻结是很正常的。在接受第一个连接之后,就再也不会调用listener.AcceptSocke来获取新的集合了。
使用这些方法的常用方法是使用异步调用、线程或任务。
编辑
举个例子:
void Start()
{
Task.Factory.StartNew(() =>
{
TcpListener listener = new TcpListener(IPAddress.Any, 12345);
listener.Start();
while (true)
{
Socket socket = listener.AcceptSocket();
Task.Factory.StartNew(() =>
{
byte[] b = new byte[100];
int k = socket.Receive(b);
});
}
});
}发布于 2013-09-27 02:29:13
在你收到数据之前,socket.Receive(b);和Accept()会阻塞当前线程,你可以在这里做几件事:
1)创建一个接收数据的独立线程,放入一个队列,由主线程检查。但在许多客户端连接的情况下,这是不可取的。
2)您可以使用套接字的异步方法:示例如下:http://csharp.vanlangen.biz/network-programming/async-sockets/asyncsocketreader/还有一个非阻塞监听器的示例。
异步监听程序如下所示:
public class SocketEventArgs : EventArgs
{
public Socket Socket { get; private set; }
public SocketEventArgs(Socket socket)
{
Socket = socket;
}
}
/// <author>Jeroen van Langen</author>
/// <source>http://http://csharp.vanlangen.biz/network-programming/async-sockets/easysocketlistener/</source>
public class EasySocketListener : IDisposable
{
private Socket _socket;
public void Start(int port)
{
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Bind(new IPEndPoint(IPAddress.Any, port));
_socket.Listen(8);
StartAccepting();
}
private void StartAccepting()
{
try
{
_socket.BeginAccept((asyncResult) =>
{
try
{
Socket clientSocket = _socket.EndAccept(asyncResult);
if (OnSocketAccept != null)
OnSocketAccept(this, new SocketEventArgs(clientSocket));
StartAccepting();
}
catch { }
}, null);
}
catch { }
}
public void Dispose()
{
if (_socket != null)
{
_socket.Dispose();
_socket = null;
}
}
public event EventHandler<SocketEventArgs> OnSocketAccept;
}当有新的客户端连接时,将调用OnSocketAccept。
https://stackoverflow.com/questions/19035780
复制相似问题