使用套接字C编译函数上的警告
这是我的节目:使用套接字C编译函数上的警告,c,sockets,function,C,Sockets,Function,这是我的节目: 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,
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 socket\n");
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 bind\n");
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 connessione\n");
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 \0*/
filename[rc] = '\0';
if (filename[strlen(filename)-1] == '\n')
filename[strlen(filename)-1] = '\0';
if (filename[strlen(filename)-1] == '\r')
filename[strlen(filename)-1] = '\0';
/* inet_ntoa converte un hostname in un ip decimale puntato */
fprintf(stderr, "Ricevuta richiesta di inviare il file '%s' dall' indirizzo %s\n", 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': %s\n", 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 file\n");
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 bytes\n", rc, (int)stat_buf.st_size);
onexit(newsockd, sockd, fd, 3);
}
onexit(newsockd, NULL, fd, 4);
}
close(sockd);
exit(EXIT_SUCCESS);
}
我无法理解为什么会出现此错误:(警告消息看起来很清楚: 在您删除的代码中,在
main
中调用函数onexit
,该函数期望其参数1为带指针的int
。您应该输入int
再一次。您定义了自己的函数
onexit
,如下所示:
void onexit(int c, int s, FILE *fp, int flag);
onexit(NULL, sockd, NULL, 1);
您选择它想要作为参数1的int
。然后,当您按如下方式调用它时:
void onexit(int c, int s, FILE *fp, int flag);
onexit(NULL, sockd, NULL, 1);
您将它作为参数1指定为NULL
,它是一个指针,而不是int
因此,编译器警告您它必须从指针生成一个整数。警告消息看起来很清楚: 在您删除的代码中,在
main
中调用函数onexit
,该函数期望其参数1为带指针的int
。您应该输入int
再一次。您定义了自己的函数
onexit
,如下所示:
void onexit(int c, int s, FILE *fp, int flag);
onexit(NULL, sockd, NULL, 1);
您选择它想要作为参数1的int
。然后,当您按如下方式调用它时:
void onexit(int c, int s, FILE *fp, int flag);
onexit(NULL, sockd, NULL, 1);
您将它作为参数1指定为NULL
,它是一个指针,而不是int
因此,编译器警告您,它必须从指针生成一个整数。顺便说一句,如果rc恰好为零,下面的代码片段会做一些糟糕的事情:
filename[rc] = '\0';
if (filename[strlen(filename)-1] == '\n')
filename[strlen(filename)-1] = '\0';
if (filename[strlen(filename)-1] == '\r')
filename[strlen(filename)-1] = '\0';
最好先检查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可以等于sizeof filename),可以使用
if((rc = recv(newsockd, filename, sizeof filename -1, 0)) < 0){...}
if((rc=recv(newsockd,filename,sizeof filename-1,0))<0{…}
顺便说一句,如果rc恰好为零,下面的代码片段会做一些糟糕的事情:
filename[rc] = '\0';
if (filename[strlen(filename)-1] == '\n')
filename[strlen(filename)-1] = '\0';
if (filename[strlen(filename)-1] == '\r')
filename[strlen(filename)-1] = '\0';
最好先检查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可以等于sizeof filename),可以使用
if((rc = recv(newsockd, filename, sizeof filename -1, 0)) < 0){...}
if((rc=recv(newsockd,filename,sizeof filename-1,0))<0{…}
注意,这里还有第二种错误——他正在调用close onint
and我如何替换“null”如果我没有参数,就进入函数吗?@polslinux你说你的函数需要一个int
。给它一个int
!0
是一个int
,例如,就像1
、-1
或42
是一样!注意这里有第二种类型的错误---他正在调用int
,我该怎么做呢ute“空”如果我没有参数,就进入函数?@polslinux你说你的函数需要一个int
。给它一个int
!0
是一个int
,例如,就像1
、-1
或42
一样!看起来你把fopen/fclose和open/close混淆了。警告是关于调用onexit
>,那么也许你应该展示你如何调用它?而且,几乎所有的警告都是关于你向该函数传递了错误的参数。只需检查警告消息中引用的行,并检查你如何调用该函数。此外,调用你的函数onexit
可能是一个错误的命名选择,因为它很容易与系统库混淆退出时返回功能。很抱歉,您是对的:(我已经用main更新了我的代码!看起来你把fopen/fclose与open/close混淆了。警告是关于调用onexit
,所以也许你应该展示一下如何调用它?而且,几乎所有的警告都是关于你向该函数传递了错误的参数。只需查看警告消息中引用的行,然后检查你是如何调用的。)调用函数。另外,调用函数onexit
可能是一个错误的命名选择,因为它很容易与退出时的系统库函数混淆。对不起,你说得对:(我用main更新了我的代码!感谢你提供的非常有用的信息:D感谢你提供的非常有用的信息:D