【问题标题】:receiving TCP connection issues接收 TCP 连接问题
【发布时间】:2013-09-26 18:21:57
【问题描述】:

我已经设法设置它,以便我的统一应用程序可以接收 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);
        }

    }
}

【问题讨论】:

    标签: c# sockets tcp unity3d


    【解决方案1】:

    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);
                    });
                }
            });
    }
    

    【讨论】:

    • 你能举个例子说明我如何根据你的建议修改我的代码吗?
    【解决方案2】:

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 2016-08-13
      相关资源
      最近更新 更多