【问题标题】:why do I get, image can't be displayed because of error with my code?为什么我会因为我的代码错误而无法显示图像?
【发布时间】:2017-04-23 17:42:13
【问题描述】:

我正在尝试加载用户指定的图像 Koala.jpg(来自浏览器),但最终会出现一个永无止境的加载屏幕,然后无法显示图像错误。这是为什么呢?

void *connectionThread(void *socket_desc){

    FILE* fd;
    char buffer[256];
    int newsockfd = *(int*)socket_desc;
    int n;  
    magic_t myt = magic_open(MAGIC_ERROR|MAGIC_MIME_TYPE);
    magic_load(myt,NULL);

    bzero(buffer,256);

     while (1)
     {memset(buffer, 0, 255);n = read(newsockfd,buffer,255);
     if (n < 0) error("ERROR reading from socket");//error checking

     printf("Here is the message: %s\n",buffer);    

     if((strncmp(buffer,"GET",3) == 0)){ //GET request
        char *header = "HTTP/1.1 200 OK\r\nContent-Type: ";

    //st_size filesize = stat(buffer, &st);

        char *token = strtok(buffer," ");
    if(token !=NULL)
        token = strtok(NULL, " ");
    token = strtok(token,"\n");
    token = strtok(token,"/");

    fd = fopen(token, "rb");

    send(newsockfd,header,strlen(header),0);
    printf("token is: %s\n",token);
    printf("magic output: '%s'\n",magic_file(myt,token));   
    //write(newsockfd,"<",strlen("<"));  
    write(newsockfd,magic_file(myt,token),strlen(magic_file(myt,token))); //get Content-type
    //write(newsockfd,">",strlen(">"));
    write(newsockfd,"\r\n",strlen("\r\n"));
    write(newsockfd,"Content-Length: ",strlen("Content-Length: "));
    write(newsockfd,"780831\r\n\r\n",strlen("780831\r\n\r\n"));



     }

     if ((strncmp(buffer,"quit",4) == 0)) //quit
    break;
     n = write(newsockfd,"I got your message\n May I have another\n",40);
     if (n < 0) error("ERROR writing to socket");
     }
     write(newsockfd,"Ok, I am quitting\n",18);
     fclose(fd);
     close(newsockfd);
     magic_close(myt);
    pthread_exit(NULL);
    return 0;
}

这是我制作套接字并绑定它的方法,以防万一出现问题。

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno,c;
     struct sockaddr_in serv_addr, cli_addr;
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
        error("ERROR opening socket");
    puts("Created socket");

     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);


     if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
              error("ERROR on binding");


     listen(sockfd,5);

     c = sizeof(struct sockaddr_in);
    pthread_t thread_id;

    while((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*)&c))){
        if (newsockfd < 0) 
                error("ERROR on accept");

        pthread_create(&thread_id, NULL, connectionThread, (void *)&newsockfd);

    }
    close(sockfd);
     return 0; 
}

【问题讨论】:

    标签: c server


    【解决方案1】:

    首先,newsockfd 上没有同步。您将newsockfd 的地址传递给线程,但随后主线程更改了它的值。您决不能允许在一个线程中访问一个对象,而另一个线程正在或可能正在修改它。你用newsockfd打破了这条规则。

    第二:

     printf("Here is the message: %s\n",buffer);    
    

    %s 格式说明符用于 C 风格的字符串。此时,buffer 包含任意图像数据。

    第三:您的代码从传入的 TCP 连接中读取一些字节,然后就好像它已经读取了一条消息一样。但你从来没有读过一条消息。您没有读取消息的代码。如果您的应用程序要使用消息,则需要编写代码来接收消息。只是在套接字上调用recv 不会读取消息,因为 TCP 协议不是消息协议。

    您可能有更多问题,但这些是最严重的。

    此外,从性能的角度来看,不断将这么小的数据写入连接是很糟糕的。相反,在缓冲区中组装更大的块并减少对write 的调用。

    【讨论】:

    • buffer 是 URL 行,它被读取然后解析以获取要显示的图像。它如何包含图像数据?你也说我应该使用互斥锁来同步。新闻社?不应该每个线程都有自己的变量newsockfd吗?
    • 另外你是什么意思,只是在套接字上调用 recv 不会读取我从不在我的代码中使用 recv?
    猜你喜欢
    • 1970-01-01
    • 2013-01-31
    • 2020-12-14
    • 1970-01-01
    • 2016-09-10
    • 2020-02-27
    • 2017-01-13
    • 2016-05-02
    • 2021-04-25
    相关资源
    最近更新 更多