【问题标题】:Linux C programingLinux C 编程
【发布时间】:2018-02-16 21:15:54
【问题描述】:

这是我第一次在这里提出问题,所以我希望我不会犯任何错误...... 我正在做一个服务器-客户端程序,当我运行客户端时出现此错误,我有“核心转储错误”。

我想我知道错误在哪里,但我不知道如何解决它。 我有 2 个结构:

typedef struct {
    int pid;
    int cmd; //1 -login,2-registrar,3-tecla
    char login[100];
    char pw[100];
    int tecla;
} PEDIDO;

typedef struct {
    int cmd;
    int res;
    BONECO *b;
} RESPOSTA;

服务器通过命名管道向客户端发送数据时的代码:

int main(int argc, char *argv[], char *envp[]){
//...
     i = read(fd, &p, sizeof (p));
                    printf(">>> Li %d bytes\n", i);
                    printf("User : %s PID : %d\n", p.login, p.pid);
                    if (p.cmd == 1) { //LOGIN

                        char user_fd[100], pw_fd[100];
                        FILE *f = fopen(argv[1], "r");
                        if (!f) {
                            printf("Erro ao abrir ficheiro\n");
                            exit(0);
                        }
                        while ((fscanf(f, "%s %s ", user_fd, pw_fd))) {
                            if (strcmp(p.login, user_fd) == 0 && strcmp(p.pw,pw_fd) == 0) {
                                printf("\nLOGIN CORRECTO!!!\n");
                                for (i = 0; i < 20; i++) {
                                    if (clientes[i][0] != p.pid && clientes[i][0] == -1) {
                                        clientes[i][0] = p.pid;
                                        break;
                                    }
                                }
                                sprintf(cli_fifo, "ccc%d", p.pid);
                                fd_resp = open(cli_fifo, O_WRONLY);
                                r.cmd = 1;
                                r.res = 1;
                                i = write(fd_resp, &r, sizeof (r));
                                close(fd_resp);
                                fclose(f);
                                break;
                            }

//...

}

客户端从服务器接收数据的代码:

void *recebe_msg(void *dados) {
    int i;
    sprintf(cli_fifo, "ccc%d", getpid());
    mkfifo(cli_fifo, 0600);
    fd_resp = open(cli_fifo, O_RDWR);
    menu();
    do {
        i = read(fd_resp, &r, sizeof (r));
        if (ESTADO == 0) {
            if (r.cmd == 1 && r.res == 1) { // OK
                ESTADO = 1;
                wclear(win);
                mvwprintw(win, 10, 14, "Login efectuado com sucesso!");

                wprintw(win, "BONECO %d, %d , %d , %d ",r.b[0].num,r.b[0].humano,r.b[0].remate,r.b[0].tempo);

                wrefresh(win);
                sleep(3);
                desenha_campo();
            }
            if (r.cmd == 1 && r.res == 0) { // NOK
                wclear(win);
                mvwprintw(win, 10, 14, "Senha e/ou login incorrectos!!!");
                wrefresh(win);
                sleep(3);
                menu();
            }
            if (r.cmd == 2 && r.res == 0) {
                wclear(win);
                mvwprintw(win, 10, 14, "Login já está em uso!");
                wrefresh(win);
                sleep(3);
                menu();
            }
            if (r.cmd == 2 && r.res == 1) {
                wclear(win);
                mvwprintw(win, 10, 14, "Registo efectuado com sucesso!");
                wrefresh(win);
                sleep(3);
                menu();
            }

            if (r.cmd == 9) { // sair
                FIM = 1;
            }
        } else if (ESTADO == 1 || ESTADO == 2) {
            wclear(win3);
            scrollok(win3, TRUE);
            keypad(win3, TRUE);
            noecho();
            if (r.cmd == 3) { // actualizacao de jogadores
                desenha_campo();
                desenha_jogadores();
            } else if (r.cmd == 9) { // sair
                FIM = 1;
            }
        }
    } while (!FIM);

    close(fd_resp);
    unlink(cli_fifo);
    pthread_exit(0);
}

OBS:我认为错误出现在 struct RESPOSTA 的第三个字段上,但我不知道如何解决它

【问题讨论】:

  • 您好!欢迎来到 SO 社区!请发布每个变量和结构的定义(您参考 struct BONECO,但没有发布它的声明)。此外,使用选项 -ggdb 编译您的代码,然后在 gdb 下运行您的代码。当您遇到分段错误时,请使用命令“bt”并在此处发布。祝你好运!
  • typedef struct { int humano; // pid int posXant, posYant; // posicao 前 int posX, posY; // posicao destino no ecra int num; // numJog int tempo; //vel int remate;诠释平等; } BONECO;
  • 好的,我的假设被证明是正确的,我创建了答案。另外,这个程序会做什么?

标签: c linux struct pthreads named-pipes


【解决方案1】:

您在这里阅读 BONECO 结构:

    i = read(fd_resp, &r, sizeof (r));

请注意,BONECO 被声明为指针,而不是实际数据。

但在这里你尝试读取这些数据:

    wprintw(win, "BONECO %d, %d , %d , %d ",r.b[0].num,r.b[0].humano,r.b[0].remate,r.b[0].tempo);

当您尝试访问 r.b[0] 时,您会遇到分段错误,因为您尝试取消引用 b 指针,该指针指向...未知位置。这会按计划导致错误。

我建议将你的结构修改为:

typedef struct {
    int cmd;
    int res;
    int count_of_boneco;
    BONECO b[];
} RESPOSTA;

如果您分配了足够大的缓冲区,则可以读取所有数据,然后立即取消引用。

【讨论】:

  • 是的,它工作但客户端没有收到“RESPOSTA.b”的数据。它是空的
  • 修复你的服务器逻辑到新的结构布局
猜你喜欢
  • 2016-07-22
  • 1970-01-01
  • 1970-01-01
  • 2016-07-13
  • 2013-12-19
  • 2015-05-04
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多