每当我尝试给出一个像/home/...../tulsaqueen.mp3之类的文件时,程序给出了分割故障。GDB说这与strlen((有关,但我无法弄清楚。为什么会发生? 我正在创建服务器,并且需要处理我的.jpg每次都可以工作,但是.mp3不行。
void *connectionThread(void *socket_desc){
char buffer[1024];
int newsockfd = *(int*)socket_desc;
int n;
magic_t myt = magic_open(MAGIC_ERROR|MAGIC_MIME_TYPE);
magic_load(myt,NULL);
bzero(buffer,256);
FILE * picture;
int size;
char *str_size = malloc(100);
struct stat sb;
int fd = open("TulsaQueen.mp3", O_RDONLY );
fstat( fd, &sb );
while (1)
{memset(buffer, 0, 1024);n = read(newsockfd,buffer,1024);
if (n < 0){ printf("ERROR reading from socket"); close(newsockfd);pthread_exit(NULL);}
printf("%s",buffer);
char *token = strtok(buffer," ");
if(token != NULL)
token = strtok(NULL, " ");
printf("%sn",token);
if(strcmp(magic_file(myt,token),"audio/mpeg") == 0){
write(newsockfd,"HTTP/1.1 200 OKrn",strlen("HTTP/1.1 200 OKrn"));
write(newsockfd,"Content-Length: ",strlen("Content-Length: "));
snprintf(str_size,100,"%li",sb.st_size);
write(newsockfd,str_size,strlen(str_size));
write(newsockfd,"rn",strlen("rn"));
write(newsockfd,"Content-Type: ",strlen("Content-type: "));
printf("magic output: '%s'n",magic_file(myt,token));
write(newsockfd,magic_file(myt,token),strlen(magic_file(myt,token)));
write(newsockfd,"rnConnection: keep-alive",strlen("rnConnection: keep-alive"));
write(newsockfd,"rnrn",strlen("rnrn"));
write( newsockfd, &sb.st_size, sizeof( sb.st_size ) );
sendfile( newsockfd, fd, 0, sb.st_size );
}
if(strcmp(magic_file(myt,token),"image/jpeg") == 0){
picture = fopen (token, "r");
fseek(picture,0,SEEK_END);
size = ftell(picture);
fseek(picture,0,SEEK_SET);
char file_buf[size];
snprintf(str_size,16,"%d",size);
//Header for HTTP standards
write(newsockfd,"HTTP/1.1 200 OKrn",strlen("HTTP/1.1 200 OKrn"));
write(newsockfd,"Content-Length: ",strlen("Content-Length: "));
write(newsockfd,str_size,strlen(str_size));
write(newsockfd,"rn",strlen("rn"));
write(newsockfd,"Content-Type: ",strlen("Content-type: "));
write(newsockfd,magic_file(myt,token),strlen(magic_file(myt,token))); //get Content-type
write(newsockfd,"rnConnection: keep-alive",strlen("rnConnection: keep-alive"));
write(newsockfd,"rnrn",strlen("rnrn"));
rewind(picture);
while(!feof(picture)){
fread(file_buf, sizeof(char), sizeof(file_buf), picture);
write(newsockfd, file_buf, sizeof(file_buf));
bzero(file_buf, sizeof(file_buf));
}
}
}
close(fd);
free(buffer);
fclose(picture);
close(newsockfd);
magic_close(myt);
pthread_exit(NULL);
return 0;
}
这是我遇到的错误
螺纹2" a.out"接收到信号sigsegv,分割故障。 (GDB(哪里 (0(strlen((at ../sysdeps/x86_64/strlen.s:106(1( _io_puts(str = 0x0(在ioputs.c:35(2( 0x0000000000401623在连接thread(((3(0x00007fffffff7bc16ba中 start_thread(arg = 0x7ffff73b6700(at pthread_create.c:333(4( 0x00007ffff76d782d in clone((at at ../sysdeps/unix/sysv/linux/x86_64/clone.s:109
代码中的一个错误可能解释了问题,与缓冲区大小, memset
和 read
...
缓冲区正好为1024个字节。您将所有这些字节设置为0
,然后阅读最多1024个字节。
但是,当您完全读取1024字节时,末尾没有任何NUL
(0(字节时会发生什么?...
...如果发生这种情况的情况比strlen
在搜索NUL
字节时会溢出(BYTE 1025及以上(,则结果是分段故障。
解决此特定问题的一种方法是阅读1023字节...即:
memset(buffer, 0, 1024);
n = read(newsockfd,buffer,1023);
解决此特定问题的更好方法(如注释中建议(是使用n
设置NUL字节值。即:
n = read(newsockfd,buffer,1023);
if (n < 0) {
// ...
}
buffer[n] = 0;
这样,您确保在分配的缓冲区中始终存在一个nul字节。
我应该指出,用 strtok
将字符串化,以及使用str*
函数来解析传入数据,这有些无效,可能会产生意外的错误/结果...
...尤其是当您处于多线程环境中...
例如, strtok
是不是线程安全...即使存在线程安全的变化,也不是理想的。
此外,它可能会无意中损坏传入的数据 - 毕竟,您仅使用第一个"代币",因此我认为您希望其余数据保持不变。
祝你好运!
P.S。
strlen(magic_file(myt,token))
-如果magic_file(myt,token)
是无效的字符串(即null(?strlen("rnrn")
总是4 ...为什么要使用函数来调用?free(buffer)
应该是free(str_size)