Идея этого небольшого проекта заключается в разработке приложения чата с той разницей, что я хочу отправлять объекты вместо простых строк. Пока это то, что у меня есть.Исключение из памяти с BeginRead
Если я десериализую конструктор, он отлично работает (на данный момент у пользователя есть только 2 строковых поля), однако я планирую, что у вас будет несколько клиентов, отправляющих данные на сервер в любое время. Мне сложно понять, как это работает и как исправить ошибку (например, это дает «Исключение типа« Исключение System.OutOfMemoryException »было выбрано.» В строке Deseralize) даже после прочтения документации MS, и я бы как некоторые идеи от вас, ребята.
Обратите внимание на то, кто пытается скомпилировать это: Binaryformatter имеет способ сделать это, как и в: Предположим, что UserDTO имеет строку свойств Имя, строка Email Применяя этот класс к клиенту и серверу, его необходимо построить с помощью класса библиотеку и добавить ссылку на это в оба проекта, потому что как-то бинарныйформатор говорит, что даже если вы создаете один и тот же класс в обоих проектах, десериализируя утверждения, он не может отобразить объект. Я оставлю образец клиента, который я использую ниже.
Сервер:
class Program {
const int serverPort = 60967;
static List<UserConnection> clientList = new List<UserConnection>();
static TcpListener listener;
static Thread listenerThread;
static void Main(string[] args) {
listenerThread = new Thread(new ThreadStart(DoListen));
listenerThread.Start();
Console.WriteLine("Server Started");
//while (true) {
string a = Console.ReadLine()
//}
}
static void DoListen() {
try {
listener = new TcpListener(System.Net.IPAddress.Any, serverPort);
listener.Start();
Console.WriteLine("Listening [...]");
do {
UserConnection client = new UserConnection(listener.AcceptTcpClient());
//clientList.Add(client);
Console.WriteLine("New connection found");
} while (true);
}
catch (Exception ex) {
Console.WriteLine(ex.ToString());
}
}
}
public class UserConnection {
private TcpClient clientInfo;
private byte[] readBuffer = new byte[2000];
const int READ_BUFFER_SIZE = 2000;
public UserConnection(TcpClient client) {
clientInfo = client;
clientInfo.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(StreamReceiver), null);
}
private void StreamReceiver(IAsyncResult ar) {
try
{
if (client.GetStream().CanRead) {
lock (clientInfo.GetStream()) {
var strm = clientInfo.GetStream();
int BytesRead = clientInfo.GetStream().EndRead(ar);
BinaryFormatter formatter = new BinaryFormatter();
var mydat = (UserDTO)formatter.Deserialize(strm);
}
lock (clientInfo.GetStream()) {
clientInfo.GetStream().BeginRead(readBuffer, 0, READ_BUFFER_SIZE, new AsyncCallback(StreamReceiver), null);
}
}
catch (Exception e) {
Console.WriteLine(ex.ToString());
}
}
Клиент:
class Program {
static void Main(string[] args) {
ConnectResult("localhost", 60967);
Console.ReadLine();
}
}
static string ConnectResult(string ip, int port) {
try {
TcpClient client = new TcpClient(ip, port);
AttemptLogin(client);
return "Connection Succeeded";
}
catch (Exception ex) {
return "Server is not active. Please start server and try again. " + ex.ToString();
}
}
static void AttemptLogin(TcpClient client) {
UserDTO obj = new UserDTO("email", "username");
IFormatter formatter = new BinaryFormatter();
var stream = client.GetStream();
formatter.Serialize(stream, obj);
Console.WriteLine("Sent Object");
}
}
Когда выполняется 'while (true);' loop exit? (Ответ: когда у программы заканчивается память, я полагаю) – Quantic
Просто для тестирования он никогда не выйдет, это в основном десериализующая часть, которая мне тяжело (при работе со строкой и потоковедом она работает просто отлично с несколькими клиенты) – abr
@Quantic Я сомневаюсь, что проблема связана с тем, что цикл не увеличивает объем используемой памяти. – EJoshuaS