2013-09-26 142 views
2

我已经设置好了,所以我的统一应用程序可以接收tcp数据。但是,当我运行该项目时,整个应用程序将冻结,并且在收到消息之前不会执行任何操作。然后,一旦接收到消息,它将打印出该消息,并且不会让我的客户端再次连接到它。接收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); 
     } 

    } 
} 

回答

2

listener.AcceptSocketsocket.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); 
       }); 
      } 
     }); 
} 
+0

请问您可以举一个例子说明如何修改我的代码,请告诉您的建议? – N0xus

0

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将被调用。