C UDP сеть, извлечение чисел из сообщения дейтаграммы - PullRequest
1 голос
/ 26 марта 2012

Я занимаюсь разработкой сетевого программного обеспечения в рамках университетского экзамена.Программное обеспечение почти закончено, но на самом деле я заканчиваю параллельную часть (с помощью fork ()).Мои потребности состоят в том, чтобы обмениваться между клиентом и сервером этими двумя сообщениями как рукопожатие.Вот пример: PING: 3506: СКАЧАТЬ PONG: 5605

Вот мой способ обработки этих сообщений: На стороне клиента, это хост, который отправляет PING: 3506: СКАЧАТЬ, я написал

int *childLocalPort;
childLocalPort = malloc(sizeof(int));
childLocalPort[0] = (SERV_PORT_OFFSET + getPort(&portArray, &pidArray, &arrayCounter, cpid));

char *pingProcedureString;
pingProcedureString = malloc(30*sizeof(char));
strcpy(pingProcedureString, "PING:");

char *itoaPortBuffer;
itoaPortBuffer = malloc(6*sizeof(char));
itoa((childLocalPort[0]), itoaPortBuffer, 10);
strcat(pingProcedureString, itoaPortBuffer);
strcat(pingProcedureString, ":DOWNLOAD");
if (sendto(sockfd, pingProcedureString, strlen(pingProcedureString), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
    perror("errore in sendto1");
    exit(1);
}
free(itoaPortBuffer);
free(pingProcedureString);



n = recvfrom(sockfd, buff, MAXLINE, 0, NULL, NULL);
buff[n] = 0;
if(strcmp(buff,"PONG"))
{
    int *childRemotePort;
    childRemotePort = malloc(sizeof(int));
    strtok(buff, ":");
    childRemotePort[0] = ntohs(strtok(NULL, ":"));

    printf("Remote port is %d\n", childRemotePort[0]);



    close(pipeLocalPort[0]);          /* Close unused read end */
    write(pipeLocalPort[1], childLocalPort, sizeof(int)
    close(pipeLocalPort[1]);          /* Reader will see EOF */
    close(pipeRemotePort[0]);
    write(pipeRemotePort[1], childRemotePort, sizeof(int));
    close(pipeRemotePort[1]);
}

На стороне сервера, то есть хост, который отправляет PONG: 5605, я написал

if ((n > 0) && strcmp(recvline,"PING"))
{
    int *childRemotePort;
    childRemotePort = malloc(sizeof(int));
    strtok(recvline, ":");
    char *buffTemp;
    buffTemp = calloc(5, sizeof(char));
    strcpy(buffTemp,strtok(NULL, ":"));
    childRemotePort[0] = ntohs(atoi(buffTemp));
    strtok(recvline, ":");
    printf("Remote child client port is: %d\n", childRemotePort[0]);
}

Как вы можете заметить, часть PONG отсутствует, потому что я хотел бы сосредоточиться на первой нерабочей части,Сервер правильно получает (как я вижу из Wireshark) сообщение PING: 3506: DOWNLOAD, но он говорит мне, что он получил 19476 вместо 3506, и это не так.Я также заметил, что если я пытаюсь отправлять числовые сообщения без преобразования их в сетевой порядок байтов, все становится еще хуже.Я борюсь с этим уже много дней и больше не знаю, о чем думать.

1 Ответ

1 голос
/ 26 марта 2012

когда вы отправляете PING от клиента, клиент не может сделать ntohs на целочисленном порту перед преобразованием в ascii, но при получении на сервере вы делаете ntohs, я думаю, что это вызывает ошибку. Выполнение чего-либо в этих строках на стороне клиента PING может помочь, однако это все еще подвержено ошибкам, если endianness сервера и клиента отличается.

char *itoaPortBuffer;
itoaPortBuffer = malloc(6*sizeof(char));
itoa(ntohs(childLocalPort[0]), itoaPortBuffer, 10);
strcat(pingProcedureString, itoaPortBuffer);
strcat(pingProcedureString, ":DOWNLOAD");
...