Итак, у меня есть сервер и клиент.
Сервер - консольные приложения .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;
}
}
Спасибо.