Последовательная потеря данных через сокеты (но не при использовании локальных соединений)

0

Я пытаюсь устроиться с программированием сокетов. Я написал клиент/серверную игру и вижу некоторые странные результаты.

Ниже приведен код для клиентской части:


while(1){
        char response[100];
        memset(&buf[0], 0, sizeof(buf));
        //buf[numbytes] = '\0';
        socklen_t addr_len = sizeof their_addr;
        if ((numbytes = recvfrom(sockfd, buf, MAXDATASIZE-1, 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) {
            perror("recv");
            exit(1);
        }

        if (strcmp(buf, "exit 99") == 0){
            close(sockfd);
            return 0;
        }

        printf("%s\n",buf);

        std::cin >> response;
        struct msgstruct message;
        message.send_data = response;
        message.length = strlen(message.send_data);
        int n   = sendto(sockfd, response, strlen(response), 0, p->ai_addr, p->ai_addrlen);
    }

Это происходит через "сервер" через следующий фрагмент кода:

int StartMasterMind(int client, sockaddr_storage addr_in) 
{
    struct sockaddr_storage their_addr = addr_in;
    socklen_t addr_len;
    char buf[MAXDATASIZE];
    buf[MAXDATASIZE] = '\0';

    sendMsg(client, "Welcome to ... M-A-S-T-E-R-M-I-N-D.\nThe game has begun.\n");

// [..] redacted for clarity 

    for (int i = 0; i < 8; ++i) {

    sendMsg(client, "Please enter your guess: ");

    addr_len = sizeof their_addr;
    recv(client, buf, MAXDATASIZE-1, 0/*, (struct sockaddr *)&their_addr, &addr_len*/);
    current_try = GetInputAsColorMap(buf);

// [..] redacted for clarity -- several for() loops below here
}



//basic message structure
struct msgstruct {
        int length;
        char* send_data;
};

//basic method for sending messages
int sendMsg(int client, char* theMsg)
{
    msgstruct message;
    message.send_data = theMsg;
    message.length = strlen(message.send_data);

    return (send(client, message.send_data, message.length, 0));
}

Поэтому, если я подключаюсь через локальный хост: ./client localhost <port>, тогда все выглядит нормально:

c@ub1:~/Documents/dev$ ./client localhost 9990
client: connecting to 127.0.0.1
Welcome to ... M-A-S-T-E-R-M-I-N-D.
The game has begun.
Please enter your guess: 

Однако при подключении по сети от другой виртуальной машины я последовательно получаю:

c@ub1:~/Documents/dev$ ./client 192.168.1.111 9990
client: connecting to 192.168.1.111
Welcome to ... M-A-S-T-E-R-M-I-N-D.
The game has begun.

Обратите внимание на недостающие. Please enter your guess: - Я немного не понимаю, что здесь делать. Я не могу понять, почему/когда/где эти данные опускаются. Из-за этого я немного боюсь продолжать, потому что я просто предполагаю, что у меня есть буфер, который переполняется и разрушает все.

  • 0
    Какой протокол вы используете? Вы могли бы показать, как создается сокет?
  • 0
    В случае, если вы используете TCP: внимательно прочитайте man-страницы для recv () / send () и узнайте, что по крайней мере для сокетов эти две функции не обязательно получают / отправляют столько байтов, сколько им было сказано, но мало. Так что циклический подсчет таких вызовов до тех пор, пока все данные или терминатор не будут получены / отправлены, является хорошей идеей, не говоря уже о существенной необходимости.
Теги:
sockets
buffer

1 ответ

2

Вы делаете все обычные ошибки. Вы предполагаете, что один посылает равный одному. Вы не используете счетчик чтения, возвращаемый recv() при использовании его буфера приема. Вы считаете, что TCP - это протокол обмена сообщениями. Это протокол байтового потока.

  • 0
    Три удара, и вы вышли.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню