【问题标题】:UDP Client Segmentation ErrorUDP 客户端分段错误
【发布时间】:2014-09-29 19:23:03
【问题描述】:

请帮忙!这是几个小时后到期的,我在网上搜索时没有运气

代码:

/* 描述: 客户端应首先向 LocationServer 发送数据报。 LocationServer 将监听主机 c-lnx001.engr.uiowa.edu 的端口号 23510。 此数据报中包含的消息应该是指定的 UserID(没有空字符、空格、换行符或其他无关字符)。 LocationServer 将使用包含以下信息的数据报进行响应: [WeatherServer 主机名] [WeatherServer 端口#] */

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>  /* for fprintf */
#include <string.h> /* for memcpy */
#include <strings.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>

#define SIZE 2048

int main(){

struct hostent *hp;     /* host information */
struct sockaddr_in servaddr;    /* server address */
char *my_message = "laura\0";/*USERID as message to server*/
char *buf_addr;
char *host = "c-lnx001.engr.uiowa.edu\0";
int port = 23510;
int fd;

/* fill in the server's address and data */
//memset((char*)&servaddr, 0, sizeof(servaddr)); ?
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(23510);

/* look up the address of the server given its name */
hp = gethostbyname("c-lnx001.engr.uiowa.edu");
if (!hp) {
    fprintf(stderr, "could not obtain address of %s\n", host);
    return 0;
}



/* put the host's address into the server address structure */
// DOESN't WORK: memcpy((void *)&servaddr.sin_addr, hp->h_addr_list[0], hp->h_length);

bcopy(hp->h_addr,(char*)&servaddr.sin_addr,hp->h_length);

if((fd = socket(AF_INET,SOCK_DGRAM, 0))<0)
{
    exit(2);

}

/* send a message to the server */
if (sendto(fd, my_message, strlen(my_message), 0, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) 
{
    perror("sendto failed");
    return 0;
}
int addrlen = sizeof(servaddr);

recvfrom(fd,buf_addr,SIZE,0,(struct sockaddr*)&servaddr,&addrlen);
printf("%s\n", buf_addr);

}

【问题讨论】:

  • char *buf_addr 在 recvfrom() 调用中使用时未初始化。
  • 非常仔细地查看网络代码中的所有 C 'string' 调用。 C 没有字符串,它有一系列必须以 nul 结尾的字符。
  • 哦 - 错过了粗体字的“紧急”请求 - 投反对票。
  • 此外,谷歌搜索“C UDP 客户端”显示:“大约 4,670,000 个结果”,第一个是一个合理的例子。请注意,recvfrom 之后是添加终止空值。 “我在网上搜索时运气不佳”——是的,没错。

标签: c segmentation-fault client-server


【解决方案1】:

我认为您的问题是您没有重置 serveraddr
这是一份工作副本

#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define IP_ADDRESS "127.0.0.1"
#define SERVER_PORT 5060

int main (int argc, char *argv[])
{
    int recBytes, clientSocket=socket(AF_INET, SOCK_DGRAM, 0);
    char buf[80], msg[]="greeting to server";
    const int msgLen = sizeof(msg);
    struct sockaddr_in serverAddr;
    socklen_t reSize;

    memset(&serverAddr, sizeof(struct sockaddr_in), 0);

    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(SERVER_PORT);
    inet_aton(IP_ADDRESS, &serverAddr.sin_addr);

    if(sendto(clientSocket, msg, sizeof(msg), 0, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) != (sizeof(msg)))
    {
        perror("sendto");
        return -1;
    }

    reSize = sizeof(struct sockaddr);
    if((recBytes = recvfrom(clientSocket, buf, sizeof(buf)-1, 0, (struct sockaddr*)&serverAddr, &reSize)) == -1)
    {
        perror("recvfrom");
        return -1;
    }
    buf[recBytes]='\0';
    printf("%s\n", buf);

    return 0;
}

【讨论】:

  • 网络代码中的 printf 被滥用几乎与 strlen() 一样多。 OP 描述的协议未定义终止空值,并且自动存储字符 buf[80] 未初始化为空值,并且 recvfrom() 调用返回的“recbytes”不用于添加终止空值。如果接收到 80 字节的数据报,buf 可能无论如何都不会保存添加的 null。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
  • 2016-10-07
  • 1970-01-01
  • 2021-07-02
相关资源
最近更新 更多