Все еще отправляю одно сообщение с TCP_NODELAY - PullRequest
0 голосов
/ 15 декабря 2018

Из того, что я понял, алгоритм Нагеля состоит в том, что он пытается отправить несколько сообщений в одном сообщении, если возможно, используя меньшую пропускную способность.

Моя проблема в том, что для университетского проекта мне придется отключить это;Сначала я должен отправить имя, затем год, месяц, день и, наконец, имя файла.

На стороне сервера мне придется обработать его в виде строки: имя / год / месяц / день / имя файла

Явно указано, что мой клиент / сервер должен работать с клиентом / серверами других студентов.Поэтому мне не разрешается просто устанавливать \ 0 или другой символ в конце каждого сообщения, а затем обрабатывать его на сервере, потому что любой студент может иметь другой конечный символ.

Мой код выглядит следующим образом

int main(int argc, char *argv[])
{
  int sockfd;
  int yes=1;
  struct sockaddr_in their_addr;
  struct hostent *he;
  if ((he=gethostbyname(argv[1])) == NULL) {
    perror("Client: gethostbyname");
    return EXIT_FAILURE;
  }

  if ((sockfd = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP))==-1) {
    perror("Client: socket");
    return EXIT_FAILURE;
  }

  their_addr.sin_family = AF_INET;
  their_addr.sin_port = htons(PORT);
  their_addr.sin_addr = *((struct in_addr*)he->h_addr);
  memset(&(their_addr.sin_zero), '\0', 8);

  if (connect(sockfd,(struct sockaddr *)&their_addr,sizeof(struct sockaddr))==-1) {
    perror("Client: connect");
    return EXIT_FAILURE;
  }

  if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(int))==-1) {
    perror("Client: setsockopt");
    return EXIT_FAILURE;
  }
  if (send(sockfd,argv[2],strlen(argv[2]),0)==-1) {
    perror("Client: send username");
    return EXIT_FAILURE;
  }

  if (send(sockfd,argv[4],4,0)==-1) {
    perror("Client: send year");
    return EXIT_FAILURE;
  }

Я думал, что это будет работать из-за строки

setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(int)

иногда также написано так (ни один из них не работает в любом случае)

setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &yes, sizeof(yes));

Я не нашелвсе, что говорит, что это должно быть сделано (я всегда использовал 0 вместо IPPROTO_TCP):

sockfd = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);

, но я нашел некоторый код с этим, поэтому я попробовал его, но он все еще не работал.На стороне сервера у меня также очень стандартный код с 5 recv (), я также пытался реализовать TCP_NODELAY, но он все еще не работал.Я сомневаюсь, что код сервера поможет, поскольку проблема, кажется, от клиента, отправляющего одно сообщение.

Итак, я хотел бы знать, что я делаю неправильно и как эффективно получать 5 разных сообщений вместо одного (в настоящее время я делаю sleep (1) между каждой отправкой, что явно не оптимально)).

Заранее спасибо за ответ

1 Ответ

0 голосов
/ 15 декабря 2018

В TCP нет сквозных «сообщений»;это протокол потока байтов.Протокол может свободно объединять байты из нескольких отправлений по своему усмотрению или разбивать одну отправку на несколько сегментов.Это означает, что если вам нужны отдельные сообщения, вы должны их придумать.Обычные методы включают в себя отправку длины перед фактическими байтами сообщения;или имеющий определенный завершающий символ (который затем должен найти получатель);или с использованием сообщений фиксированной длины (я бы посоветовал против этого, поскольку это негибко).

Все это потребует установления стандартного подхода для всех учащихся.Но так обстоит дело в реальной жизни: для общения необходимо заранее согласовать протоколы.Я не знаю мнение вашего учителя, но я бы получил хорошие оценки, если бы вы совместно определили стандарт сообщений и записали его как часть представления своей работы.

Подход «ожидания между сообщениями», который вы обнаружилидля себя - это решение для перекрестного контроля и надежды;Вы надеетесь, что ваше время ожидания превышает время, необходимое для передачи сообщения, которое может быть довольно большим, если есть сетевая ошибка.И получатель надеется, что либо (а) все байты будут доставлены одновременно, либо (б) что, если он запрашивает данные, то индикация «больше нет» означает, что он прочитал все сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...