编译带有套接字 C 的功能上的警告



这是我的程序:

 int main(int argc, char *argv[]){
    if(argc != 2){
        printf("Uso: ./server <numero porta>n");
        exit(1);
    }
    int sockd, newsockd, LunghezzaClient;
    int NumPorta = atoi(argv[1]);
    struct sockaddr_in serv_addr, cli_addr; /* indirizzo del server e del client */
    int rc, fd;
    off_t offset = 0;
    struct stat stat_buf;
    char filename[1024] = {};
    size_t fsize;
    if((sockd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
        perror("Errore creazione socketn");
        exit(EXIT_FAILURE);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */
    serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */
    serv_addr.sin_port = htons(NumPorta); /* porta htons converte nell'ordine dei byte di rete */
    serv_addr.sin_addr.s_addr = INADDR_ANY; /* dato che è un server bisogna associargli l'indirizzo della macchina su cui sta girando */
    if(bind(sockd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
        perror("Errore di bindn");
        onexit(NULL, sockd, NULL, 1);
    }
    if(listen(sockd, 5) < 0){
            perror("Errore nella funzione listen");
            onexit(NULL, sockd, NULL, 1);
    }
    LunghezzaClient = sizeof(cli_addr);
    signal (SIGINT, ( void *)sig_handler); 
    while(1){
        if((newsockd = accept(sockd, (struct sockaddr *) &cli_addr, (socklen_t *) &LunghezzaClient)) < 0){
            perror("Errore nella connessionen");
            onexit(newsockd, sockd, NULL, 2);
        }
        /* get the file name from the client */
        if((rc = recv(newsockd, filename, sizeof(filename), 0)) < 0){
            perror("Errore nella ricezione del nome del file");
            onexit(newsockd, sockd, NULL, 2);
        }
        /* Terminiamo il nome del file con NULL e se ultimo carattere è n o r lo cambiamo con */
        filename[rc] = '';
        if (filename[strlen(filename)-1] == 'n')
            filename[strlen(filename)-1] = '';
        if (filename[strlen(filename)-1] == 'r')
            filename[strlen(filename)-1] = '';
        /* inet_ntoa converte un hostname in un ip decimale puntato */
        fprintf(stderr, "Ricevuta richiesta di inviare il file '%s' dall' indirizzo %sn", filename, inet_ntoa(cli_addr.sin_addr));
        /* open the file to be sent */
        fd = open(filename, O_RDONLY);
        if (fd < 0) {
            fprintf(stderr, "Impossibile aprire '%s': %sn", filename, strerror(errno));
            onexit(newsockd, sockd, NULL, 2);
        }
        /* get the size of the file to be sent */
        if(fstat(fd, &stat_buf) < 0){
            perror("Errore fstat");
            onexit(newsockd, sockd, fd, 3);
        }
        fsize = stat_buf.st_size;
        if(send(newsockd, &fsize, sizeof(fsize), 0) < 0){
            perror("Errore durante l'invio della grandezza del filen");
            onexit(newsockd, sockd, fd, 3);
        }
        /* copy file using sendfile */
        offset = 0;
        rc = sendfile(newsockd, fd, &offset, stat_buf.st_size);
        if (rc == -1) {
            fprintf(stderr, "Errore durante l'invio di: '%s'n", strerror(errno));
            onexit(newsockd, sockd, fd, 3);
        }
        if (rc != fsize) {
            fprintf(stderr, "Trasferimento incompleto: %d di %d bytesn", rc, (int)stat_buf.st_size);
            onexit(newsockd, sockd, fd, 3);
        }
        onexit(newsockd, NULL, fd, 4);
    }
    close(sockd);
    exit(EXIT_SUCCESS);
}

但是当我尝试用gcc -Wall -O3 -o program myprogram.c编译它时,由于函数中的一些错误onexit我收到了很多警告。这是我收到的警告:

server-iterativo.c: In function ‘main’:
server-iterativo.c:51:3: warning: passing argument 1 of ‘onexit’ makes integer from pointer without a cast [enabled by default]
server-iterativo.c:23:6: note: expected ‘int’ but argument is of type ‘void *’
server-iterativo.c:56:7: warning: passing argument 1 of ‘onexit’ makes integer from pointer without a cast [enabled by default]
server-iterativo.c:23:6: note: expected ‘int’ but argument is of type ‘void *’
server-iterativo.c:92:7: warning: passing argument 3 of ‘onexit’ makes pointer from integer without a cast [enabled by default]
server-iterativo.c:23:6: note: expected ‘struct FILE *’ but argument is of type ‘int’
server-iterativo.c:97:7: warning: passing argument 3 of ‘onexit’ makes pointer from integer without a cast [enabled by default]
server-iterativo.c:23:6: note: expected ‘struct FILE *’ but argument is of type ‘int’
server-iterativo.c:104:9: warning: passing argument 3 of ‘onexit’ makes pointer from integer without a cast [enabled by default]
server-iterativo.c:23:6: note: expected ‘struct FILE *’ but argument is of type ‘int’
server-iterativo.c:108:9: warning: passing argument 3 of ‘onexit’ makes pointer from integer without a cast [enabled by default]
server-iterativo.c:23:6: note: expected ‘struct FILE *’ but argument is of type ‘int’
server-iterativo.c:111:3: warning: passing argument 2 of ‘onexit’ makes integer from pointer without a cast [enabled by default]
server-iterativo.c:23:6: note: expected ‘int’ but argument is of type ‘void *’
server-iterativo.c:111:3: warning: passing argument 3 of ‘onexit’ makes pointer from integer without a cast [enabled by default]
server-iterativo.c:23:6: note: expected ‘struct FILE *’ but argument is of type ‘int’
server-iterativo.c: In function ‘onexit’:
server-iterativo.c:131:3: warning: passing argument 1 of ‘close’ makes integer from pointer without a cast [enabled by default]
/usr/include/unistd.h:354:12: note: expected ‘int’ but argument is of type ‘struct FILE *’
server-iterativo.c:136:3: warning: passing argument 1 of ‘close’ makes integer from pointer without a cast [enabled by default]
/usr/include/unistd.h:354:12: note: expected ‘int’ but argument is of type ‘struct FILE *’

我不明白为什么我得到这个错误:(

警告消息看起来很清楚:

删除的代码中,在 main 中,调用函数onexit,该函数期望其参数 1 是带有指针的int。你应该喂一只int


再来一次。定义自己的函数onexit如下所示:

void onexit(int c, int s, FILE *fp, int flag);

您可以选择它希望参数 1 为int .然后,当您按如下方式调用它时:

onexit(NULL, sockd, NULL, 1);

将其NULL作为参数 1 指定,这是一个指针,而不是int

因此,编译器警告它必须从指针生成整数

顺便说一句,如果 rc 恰好为零,下面的代码片段会做一些令人讨厌的事情:

filename[rc] = '';
if (filename[strlen(filename)-1] == 'n')
    filename[strlen(filename)-1] = '';
if (filename[strlen(filename)-1] == 'r')
    filename[strlen(filename)-1] = '';

最好先检查 rc:

if (rc > 0 && filename[rc-1] == 'n') filename[--rc] = 0;
if (rc > 0 && filename[rc-1] == 'r') filename[--rc] = 0;

避免 2-4 次调用 strlen() 也会为你节省一些周期。

为了避免缓冲区溢出(rc 可以等于文件名的大小),您可以使用

if((rc = recv(newsockd, filename, sizeof filename -1, 0)) < 0){...}

最新更新