【问题标题】:C UDP networking, extract numbers from datagram messageC UDP网络,从数据报消息中提取数字
【发布时间】:2012-04-10 00:29:18
【问题描述】:

我正在开发一种网络软件,作为大学考试的一部分。软件快完成了,但实际上我正在完成并发部分(使用 fork())。 我的需要是在客户端和服务器之间交换这两条消息作为握手。 这里有一个例子: PING:3506:下载 乒乓:5605

这是我处理这些消息的方式: 在客户端,我写的是发送 PING:3506:DOWNLOAD 的主机

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) 您的缓冲区太小。 2) 无需使用 malloc() 分配它们,您可以轻松地在堆栈上分配几百字节大小的缓冲区。 3)您假设网络数据包是 nul 终止的。他们不是。 4) 哎呀,我忽略了buff[n] = 0; ...

标签: c udp packet datagram


【解决方案1】:

当您从客户端发送 PING 时,客户端在转换为 ascii 之前无法在整数端口上执行 ntohs ,但在服务器接收时您执行 ntohs ,我认为这是导致错误的原因。在客户端 PING 端在这些行上做一些事情可能会有所帮助,但是如果服务器和客户端的 endianness 不同,这仍然容易出错。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 2013-02-22
    • 2013-05-04
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    相关资源
    最近更新 更多