ubuntu - 为什么我的 .NET Core 服务器应用程序在 Ubuntu 中不接受连接,但在 Windows 中可以正常工作?

标签 ubuntu networking .net-core tcpclient

所以,我基本上有一个服务器和一个客户端。

服务器是一个 .NET Core 2.2 控制台应用程序,它监听传入连接,一旦打开连接,读取请求,从 MySQL 数据库中提取一些数据,然后将其发送回客户端。

客户端是一个 Xamarin Forms 应用程序,它将这些请求发送到服务器。没什么复杂的。

现在,如果我在本地 Windows 机器上运行服务器,它将开始监听分配的端口并正确接受请求并发送响应。但是,当我将它部署到旨在运行此服务器应用程序的 Ubuntu 19.04 机器时,它根本看不到传入的连接。

当然,我确定这不是网络问题,我尝试 netcat (nc -l PORT) 相关端口,它正在接收正确的数据。

这是我的服务器代码:

    public static class Server
    {
        public static Dictionary<string, Session> Sessions { get; private set; } = new Dictionary<string, Session>();

        public static int Main(string[] args)
        {
            return RunServer();
        }

        private static int RunServer()
        {
            var listener = new TcpListener(IPAddress.Loopback, ServerConfig.Port);
            int errorCode = 0;

            try
            {
                listener.Start();
                Console.WriteLine("Server running - listening to " + ServerConfig.Port + " ..."); // this is printed in Ubuntu

                while (true)
                {
                    var clientTask = listener.AcceptTcpClientAsync();

                    if (clientTask.Result != null)
                    {
                        using (TcpClient tcpClient = clientTask.Result)
                        {
                            // This line is printed in Windows/localhost, but not on the Ubuntu production machine
                            Console.WriteLine("Connected to {0}", (tcpClient.Client.RemoteEndPoint as IPEndPoint).Address);

                            string data;
                            string cmd;
                            string[] parameters;
                            string response = null;
                            NetworkStream stream = tcpClient.GetStream();

                            data = ReceiveRemoteMessage(stream); // See below

                            if (string.IsNullOrWhiteSpace(data))
                                continue;

                            parameters = data.Split(' ');
                            cmd = parameters[0];

                            try
                            {
                                // Note: the CommunicationManager class that actually processes the requests is not relevant to this question, so it's not included
                                string methodName = "Manage" + cmd + "Request";
                                var argList = new List<object>();
                                var i = 0;
                                foreach(object par in parameters)
                                {
                                    i++;
                                    if (i == 1)
                                        continue;

                                    argList.Add(par);
                                }
                                object[] args = argList.ToArray();
                                response = (string) typeof(CommunicationManager).GetMethod(methodName).Invoke(null, args);
                            }

                            catch (Exception e)
                            {
                                if (e is AmbiguousMatchException ||
                                    e is ArgumentNullException ||
                                    e is TargetException ||
                                    e is ArgumentException ||
                                    e is TargetInvocationException ||
                                    e is TargetParameterCountException ||
                                    e is MethodAccessException ||
                                    e is InvalidOperationException ||
                                    e is NotSupportedException)
                                {
                                    response = ServerResponse.InvalidRequest; // ServerResponse is a static class with read-only static string fields
                                }
                                else
                                {
                                    response = ServerResponse.GenericException;
                                }
                            }

                            if (!string.IsNullOrWhiteSpace(response))
                            {
                                SendSocketMessage(stream, response);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                errorCode = 1;
            }
            finally
            {
                listener.Stop();
            }

            Console.WriteLine($"\nExit code: {errorCode}\nPress any key to terminate.");
            Console.ReadKey();
            return errorCode;
        }

        private static void SendSocketMessage(NetworkStream stream, string message)
        {
            var encryptedMsg = Encrypt.EncryptString(message);
            stream.Write(Encoding.UTF8.GetBytes(encryptedMsg));
        }

        private static string ReceiveRemoteMessage(NetworkStream stream)
        {
            const int bufferSize = 1024;
            byte[] bytes;
            string data = string.Empty;

            while (true)
            {
                bytes = new byte[bufferSize];
                int bytesReceived = stream.Read(bytes);

                string utfString = Encoding.UTF8.GetString(bytes, 0, bytesReceived);

                if (string.IsNullOrEmpty(utfString))
                    break;

                data += utfString;

                if (bytesReceived < bufferSize)
                    break;
            }
            var decryptedMsg = Encrypt.DecryptString(data);
            return decryptedMsg;
        }
    }

这是我的客户端代码,用于 Xamarin (Mono)

public static string SendServerRequest(string request)
        {
            //
            try
            {
                TcpClient client = new TcpClient();
                client.ConnectAsync(ServerConfig.Hostname, ServerConfig.Port).Wait();

                NetworkStream stream = client.GetStream();

                var encryptedRequest = Encrypt.EncryptString(request);
                var sentBytes = Encoding.UTF8.GetBytes(encryptedRequest);
                stream.Write(sentBytes, 0, sentBytes.Length);

                const int bufferSize = 1024;
                byte[] bytes;
                string data = string.Empty;
                int totalBytesReceived = 0;

                while (true)
                {
                    bytes = new byte[bufferSize];
                    int bytesReceived = stream.Read(bytes, totalBytesReceived, bufferSize);
                    totalBytesReceived += bytesReceived;

                    string utfString = Encoding.UTF8.GetString(bytes, 0, bytesReceived);

                    if (string.IsNullOrEmpty(utfString))
                        break;

                    data += utfString;

                    if (bytesReceived < bufferSize)
                        break;
                }

                return Encrypt.DecryptString(data);
            }
            catch
            {
                return null;
            }
        }

谢谢。

最佳答案

var listener = new TcpListener(IPAddress.Loopback, ServerConfig.Port);

这就是说 TcpListener 应该(仅)监听环回地址。这意味着服务器应该监听来自本地机器的传入连接,而不是网络上的任何其他机器。

我想你想要 IPAddress.Any :
var listener = new TcpListener(IPAddress.Any, ServerConfig.Port);

关于ubuntu - 为什么我的 .NET Core 服务器应用程序在 Ubuntu 中不接受连接,但在 Windows 中可以正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58489748/

相关文章:

c# - Entity Framework Core 2.0 添加迁移不生成任何内容

ubuntu - WSL Ubuntu(Linux 的 Windows 子系统)上没有互联网连接

ubuntu - phpmyadmin.conf 和 apache.conf 丢失

sql-server - 从 Windows 连接到 Debian MSSQL

c# - 将具有一对多关系的 .Net 核心实体映射到 Angular 2 接口(interface)

javascript - 在离线(无网络)模式下显示 SVG

linux - ubuntu启动黑屏

r - 以其他用户身份运行 R 时的图形支持

c# - 有没有办法检测我使用的连接类型? WiFi、3G 还是以太网?

c++ - 无法使用 UDP 通过二进制文件发送 pdf