У меня есть небольшой игровой сервер, который я создаю, и будет иметь десятки соединений, которые постоянно отправляют данные игрока. В то время как я, наконец, выполнил некоторые основы и теперь имею передачу/получение данных, теперь я сталкиваюсь с проблемой наводнения сервера и клиента с большим количеством данных. Я попытался отключить его, но даже тогда я поражаю 90-100% процессора просто из-за приема и обработки полученных данных, запускающих процессор.NetworkStream Receive, как обрабатывать данные без использования 100% -ного процессора?
Метод ниже - голая версия приема данных с сервера. Сервер отправляет список данных, которые должен быть получен игроком, затем он проходит через этот список. Я подумал, что, возможно, вместо этого просто использовал словарь с ключом, основанным на типе, а не для цикла, но я не думаю, что это значительно улучшит его, проблема в том, что он обрабатывает данные без остановок, потому что позиции игроков постоянно обновляются , отправляется на сервер, а затем отправляется другим игрокам.
Код ниже показывает получение для клиента, получение сервера выглядит очень похоже. Как я могу начать эту проблему? Пожалуйста, будьте добры, я все еще новичок в сетевом программировании.
private void Receive(System.Object client)
{
MemoryStream memStream = null;
TcpClient thisClient = (TcpClient)client;
List<System.Object> objects = new List<System.Object>();
while (thisClient.Connected && playerConnected == true)
{
try
{
do
{
//when receiving data, first comes length then comes the data
byte[] buffer = GetStreamByteBuffer(netStream, 4); //blocks while waiting for data
int msgLenth = BitConverter.ToInt32(buffer, 0);
if (msgLenth <= 0)
{
playerConnected = false;
thisClient.Close();
break;
}
if (msgLenth > 0)
{
buffer = GetStreamByteBuffer(netStream, msgLenth);
memStream = new MemoryStream(buffer);
}
} while (netStream.DataAvailable);
if (memStream != null)
{
BinaryFormatter formatter = new BinaryFormatter();
memStream.Position = 0;
objects = new List<System.Object>((List<System.Object>)formatter.Deserialize(memStream));
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.ToString());
if (thisClient.Connected == false)
{
playerConnected = false;
netStream.Close();
thisClient.Close();
break;
}
}
try
{
if (objects != null)
{
for (int i = 0; i < objects.Count; i++)
{
if(objects[i] != null)
{
if (objects[i].GetType() == typeof(GameObject))
{
GameObject p = (GameObject)objects[i];
GameObject item;
if (mapGameObjects.TryGetValue(p.objectID, out item))
{
mapGameObjects[p.objectID] = p;;
}
else
{
mapGameObjects.Add(p.objectID, p);
}
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Exception " + ex.ToString());
if (thisClient.Connected == false)
{
playerConnected = false;
netStream.Close();
break;
}
}
}
Console.WriteLine("Receive thread closed for client.");
}
public static byte[] GetStreamByteBuffer(NetworkStream stream, int n)
{
byte[] buffer = new byte[n];
int bytesRead = 0;
int chunk = 0;
while (bytesRead < n)
{
chunk = stream.Read(buffer, (int)bytesRead, buffer.Length - (int)bytesRead);
if (chunk == 0)
{
break;
}
bytesRead += chunk;
}
return buffer;
}
Моя ставка заключается в том, что вам нужно немного поспать. – luk32
:(Работа не заканчивается, пока я сплю – Euthyphro
Я сомневаюсь, что сеть - это то, что заставляет процессор переходить на 100%, это, вероятно, обработка, которую вы делаете после получения данных. Но это то, что я не могу ответить, потому что могу Я читаю ваш код и понимаю, что вы пытались сделать и что может быть избыточным. Предлагаю вам начать оптимизацию того, что вы считаете самой тяжелой частью, и вернуться сюда и задать новый вопрос, когда вы сталкиваетесь с чем-то, что не можете решить. –