Russian Qt Forum
Ноябрь 01, 2024, 13:41 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: [НЕ РЕШЕНО] Танчики на 2 игроков по сети. ПРоблема с сервером.  (Прочитано 5734 раз)
lolbla2
Гость
« : Февраль 14, 2012, 18:52 »

Проблема в следующем: когда оба игрока двигаются или выполняют какие-то действия всё норм, но когда один ничего не делает,а другой например едет, то почему-то у того кто ничего не делает противоположный игрок передвигается рывками, то есть ощущение будто пинг ужасный, хотя на самом деле это не так, ведь когда оба двигаются у всех всё нормально. Я подумал дело в сервере? Хотя может и проблема в клиентах.

Игра состоит из серверного приложения и клиентского. Оба клиента передают инфу серверу, а сервер уже от 1 игрока передает инфу 2 игроку, а от 2-го наоборот 1-му.  Помогите кто знает как решить траблу....
Вот исходник сервера:
Структура Input
Код:
struct Input
{
   bool startflag;
   int player;
    bool t_dead;
    int t_dir;
    int t_posx;
    int t_posy;
    int t_movex;
    int t_movey;
    int b_posx;
    int b_posy;
    int b_dir;
};
На самом деле здесь есть ненужные переменные, потом их уберу, но пока дело не в этом.

Код:
struct PlayerInfo
{
    int players;
    int myPlayerNum;
};

const int startPos[6][2]={{400,400},{0,0}, {400,200} , {200,150}, {600,350}, {300,300}   };

Widget::Widget(QWidget *parent) :
    QWidget(parent)
{
    setupUi(this);
    server = new QTcpServer(this);
    socket1 = new QTcpSocket(this);
    socket2 = new QTcpSocket(this);
    connect(server, SIGNAL(newConnection()), this , SLOT(OnClientConnected()));
    server->setMaxPendingConnections(2);
    players=0;
    server->listen(QHostAddress::Any);
    label->setText(MyIp::GetMyIp()+":"+QString::number(server->serverPort()));

    player1 = new Input;
    player2 = new Input;
    player1->t_posx = 400;
    player1->t_posy = 400;
    player1->t_dir = 1;
    player1->t_dead = false;
    player2->t_posx = 0;
    player2->t_posy = 0;
    player2->t_dir = 1;
    player2->t_dead = false;
}

void Widget::OnClientConnected()
{
    players++;
    QMessageBox::information(this,"connection!","client connected!");
    switch(players)
    {
    case 1:
        socket1 = server->nextPendingConnection();
        connect(socket1, SIGNAL(readyRead()), this, SLOT(OnReceiveData()));
        connect(socket1, SIGNAL(disconnected()), this, SLOT(OnClientDisconnected()));
        this->listWidget->addItem(socket1->peerAddress().toString()+":"+QString::number(socket1->peerPort()) );
        break;
    case 2:
        socket2 = server->nextPendingConnection();
        connect(socket2, SIGNAL(readyRead()), this, SLOT(OnReceiveData()));
        connect(socket2, SIGNAL(disconnected()), this, SLOT(OnClientDisconnected()));
        this->listWidget->addItem(socket2->peerAddress().toString()+":"+QString::number(socket2->peerPort()) );
        break;
    default:
//        server->nextPendingConnection()->abort();
        players--;
        QMessageBox::information(this,"disconection!","client disconected because already 2 players!");
    }

}

void Widget::OnClientDisconnected()
{
   if (socket1->state()!=QAbstractSocket::ConnectedState)
       this->listWidget->takeItem(0);
   if(socket2->state()!=QAbstractSocket::ConnectedState)
       this->listWidget->takeItem(1);
   players--;
}

void Widget::OnReceiveData()
{
    while(socket1->bytesAvailable())
        socket1->read((char*)player1,sizeof(*player1));
    while(socket2->bytesAvailable())
        socket2->read((char*)player2,sizeof(*player2));
    SendData();

}

void Widget::SendData()
{
    socket1->write((char*)player2,sizeof(*player2));
    socket2->write((char*)player1,sizeof(*player1));
    player1->b_posx = -1;
    player1->b_posy = -1;
    player2->b_posx = -1;
    player2->b_posy = -1;

}

void Widget::SendPlayerInfo()
{
    PlayerInfo *info= new PlayerInfo;
    info->players=players;
    info->myPlayerNum=1;
    socket1->write((char*)info, sizeof(*info));
    info->myPlayerNum=2;
    socket2->write((char*)info, sizeof(*info));

}

void Widget::on_pushButton_clicked()
{
    if(players!=2)
        QMessageBox::information(this,"Fail","Can't start the game with 1 player!");
    else
        SendPlayerInfo();
}
« Последнее редактирование: Февраль 24, 2012, 19:07 от lolbla2 » Записан
Bepec
Гость
« Ответ #1 : Февраль 15, 2012, 08:39 »

А можно проектик? Хоцца посмотреть и поиграться Веселый
Записан
SimpleSunny
Гость
« Ответ #2 : Февраль 15, 2012, 12:28 »

1. Удалите из конструктора, это лишнее.
socket1 = new QTcpSocket(this);
socket2 = new QTcpSocket(this);

2. Неправильно читаете данные
while(socket1->bytesAvailable())
socket1->read((char*)player1,sizeof(*player1));

2.1 Нет гарантии, что пришли все данные, надо проверять это
if (socket1->bytesAvailable() >= FRAME_SIZE)
in >> player1;
2.2 Нельзя так читать данные напрямую в структуру, проблема может быть из-за разных Endians, выравнивания. Используйте лучше QDataStream.

3. write аналогично сделать через QDataStream

4. Установите для сокета LowDelayOption 1. После write делайте flush.
Записан
lolbla2
Гость
« Ответ #3 : Февраль 15, 2012, 13:36 »

1. Удалите из конструктора, это лишнее.
socket1 = new QTcpSocket(this);
socket2 = new QTcpSocket(this);

2. Неправильно читаете данные
while(socket1->bytesAvailable())
socket1->read((char*)player1,sizeof(*player1));

2.1 Нет гарантии, что пришли все данные, надо проверять это
if (socket1->bytesAvailable() >= FRAME_SIZE)
in >> player1;
2.2 Нельзя так читать данные напрямую в структуру, проблема может быть из-за разных Endians, выравнивания. Используйте лучше QDataStream.

3. write аналогично сделать через QDataStream

4. Установите для сокета LowDelayOption 1. После write делайте flush.

У меня раньше было через этот QDataStream, но было так что Input player1; то есть не ссылка, а сам объект и потом там всякие проверки как в примере ну и in>>player1; при этом ещё медленее работало

Надо ссылку на объект в датастрим пихать тоесть Input *player1 ?
Записан
SimpleSunny
Гость
« Ответ #4 : Февраль 15, 2012, 15:13 »

Честно говоря не понял о чем вы.
Код
C++ (Qt)
operator<<(QdataStream &out, const Input &input)
{
out << input.startflag << input.player << input.t_dead >>...;
return out;
};
operator>>(QdataStream &in, Input &input)
{
in  >> input.startflag >> input.player >> input.t_dead >>...;
return in;
};

Иcпользовать так
Код
C++ (Qt)
Input input;
QdataStream out(socket);
out << input;
Записан
lolbla2
Гость
« Ответ #5 : Февраль 15, 2012, 15:28 »

Честно говоря не понял о чем вы.
Код
C++ (Qt)
operator<<(QdataStream &out, const Input &input)
{
out << input.startflag << input.player << input.t_dead >>...;
return out;
};
operator>>(QdataStream &in, Input &input)
{
in  >> input.startflag >> input.player >> input.t_dead >>...;
return in;
};

Иcпользовать так
Код
C++ (Qt)
Input input;
QdataStream out(socket);
out << input;

Я уже так пробовал делать, ещё хуже тормозило, поэтому подумал может надо
Иcпользовать так
Код
C++ (Qt)
Input *input= new Input;
QdataStream out(socket);
out << input;

Возможно так быстрее будет работать или не влияет?
Записан
SimpleSunny
Гость
« Ответ #6 : Февраль 15, 2012, 16:30 »

Не влияет.
Записан
lolbla2
Гость
« Ответ #7 : Февраль 15, 2012, 20:29 »

Не влияет.

 просто у меня раньше через QDataStream было и ещё хуже тормозило, вот и делай выводы...
Записан
merke
Гость
« Ответ #8 : Февраль 16, 2012, 19:05 »

Не влияет.

 просто у меня раньше через QDataStream было и ещё хуже тормозило, вот и делай выводы...

Что за бред, ни чего не будет тормозить, перестрой структуру сервера, используй только датастрим и будет тебе счастье.
Записан
lolbla2
Гость
« Ответ #9 : Февраль 17, 2012, 05:43 »

Не влияет.

 просто у меня раньше через QDataStream было и ещё хуже тормозило, вот и делай выводы...

Что за бред, ни чего не будет тормозить, перестрой структуру сервера, используй только датастрим и будет тебе счастье.
На клиенте тогда ведь тоже через датастрим надо?

Да до этого было с датастримом просто, потом переделал не через датастрим быстрее стало работать
Записан
SimpleSunny
Гость
« Ответ #10 : Февраль 17, 2012, 12:03 »

На клиенте тоже через datastream.
Задержки, если и появляются, то из-за кривого сервера\клиента, но не из-за datastream.
Записан
lolbla2
Гость
« Ответ #11 : Февраль 17, 2012, 18:46 »

Не знаю тогда почему с socket1->read((char*)player1,sizeof(*player1)); и socket1->write((char*)player1,sizeof(*player1)); быстрее работает, может потому что в QDataStream ещё много всего нагружено...
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.138 секунд. Запросов: 21.