【问题标题】:How can i read html page line by line using recv? [duplicate]如何使用recv逐行读取html页面? [复制]
【发布时间】:2015-02-19 10:07:50
【问题描述】:

我尝试使用 C 语言练习套接字编程。
我试图做的是逐行阅读某些html页面,这意味着阅读直到'\ n'。
但是,问题在于,由于 recv 的属性是读取一定长度的长度,我们将其作为参数传递给 recv() 的第三个参数。
例如,

char buff[256];
.
.
recv(socknumber, buf, sizeof(buff), 0);

在这种情况下,recv 读取的字符串与 sizeof(buff) 一样多。所以我不知道如何处理'\n'

由于我是 C 处女,请给我一些提示,或者简单的代码。谢谢。

【问题讨论】:

  • 在现代 POSIX 系统上,recv 等效于 read,如果您不传递任何标志,您可以尝试使用 fdopen 将套接字解析为常规 stdio FILE,例如使用fgets 或诸如此类的东西来提取行。不幸的是,这不适用于 Windows 系统上的 Winsock。
  • "html 页面逐行"。 HTML 页面不包含行。

标签: c sockets recv


【解决方案1】:

您必须自己实现它,因为套接字传输中没有线的概念。即使在 SO 中也有很多解决方案,请参阅read line by line from a socket buffer。您还可以从套接字描述符中获取 FILE 句柄并使用 *gets 函数(如果您使用的是 Unix,请查看 fdopen)。

【讨论】:

    【解决方案2】:

    没有满足您要求的standard 实现。您需要做的是有一个合适的sending 和一个receiving 套接字程序。

    一种建议方法:

    • Sender 逐块读取 HTML 文件(假设每次读取 100 个字节)并将它们发送到 reciever
    • Receiver 接受发送方发送的数据块并写入文件。 (接收方知道块的大小)
    • 您可以在开始传输之前指定文件长度。

    你需要什么:

    此外:这是我的示例代码集

    Client 按名称请求文件,server 响应文件(如果可用,逐块)”

    服务器:

    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    #define TRUE 1
    #define FALSE 0
    #define SIZE 1024
    
    
    int main(int argc, char**argv)
    {
        /*Variable set*/
        int listenfd,connfd,n,size;
        FILE * ff;
        struct sockaddr_in servaddr,cliaddr;
        socklen_t clilen;
        char buffer[SIZE];
    
        /* Dedicated socket to listening */
        listenfd=socket(AF_INET,SOCK_STREAM,0);
    
        /* Initialize a sockaddr_in struct with our own address information for binding the socket */
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
        servaddr.sin_port=htons(32000);
    
        /* Binding */
        bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
    
        /*Listening to the socket*/
        listen(listenfd,0);
        clilen=sizeof(cliaddr);
    
        /*Wait till a client request a file*/
        connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&clilen); // the uninitialized cliaddr variable is filled in with the
        n = recvfrom(connfd,buffer,SIZE ,0,(struct sockaddr *)&cliaddr,&clilen);// information of the client by recvfrom function
        buffer[n] = '\0';
    
        printf("CLient requested %s:\n",buffer);
    
        /*Trying to open requested file*/
        ff=fopen(buffer,"r");
        if(ff==NULL){
            printf("Request file not found..!!\n");
            strcpy(buffer,"NACK");
            sendto(connfd,buffer,sizeof(buffer),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr)); 
            return(0); //exit
        }
    
        /*If file is availbe - Find the size of file*/
        fseek(ff,0L,SEEK_END);
        size=ftell(ff);
    
        fseek(ff,0L,SEEK_SET);
        sprintf(buffer,"%d",size);
    
        /*Send size of file*/
        sendto(connfd,buffer,sizeof(buffer),0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
    
    
        /*Sits in a loop and send 1000 byte chunks -Uppon ACK's from client*/
    
        int i;
        int t=TRUE;
        char c;
    
        while(t){
    
            /*Recieve client flag*/
            n = recvfrom(connfd,buffer,SIZE,0,(struct sockaddr *)&cliaddr,&clilen);
            buffer[n] = 0;
    
            /*If its not ACK then exit*/
            if(strcmp(buffer,"ACK")){
                printf("CLient failled to grab data chunks..\n");
                return(0);
            }
    
            /*Else read 1000 bytes*/
            for(i=0;i<1000;i++){
                c=fgetc(ff);
                buffer[i]=c;
                if(c==EOF){
                    t=FALSE;
                    break;
                }
            }
    
            /*Send red data chunk*/
            sendto(connfd,buffer,i,0,(struct sockaddr *)&cliaddr,sizeof(cliaddr));
            printf("Sending.. %d bytes \n",i);
        }
    
        /*Close file*/
        fclose(ff);
    
    
        return 0;
    }
    

    客户:

    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    /*Macros*/
    #define SIZE 1024
    #define TRUE 1
    
    int main(int argc, char**argv)
    {
        /*Variable Set*/
        int sockfd,n,len;
        FILE * ff;
        struct sockaddr_in servaddr;
        char buffer[SIZE];
    
        if (argc != 2)
        {
            printf("usage:  ./%s <IP address>\n",argv[0]);
            return -1;
        }
        /* socket to connect */
        sockfd=socket(AF_INET,SOCK_STREAM,0);
    
        /* IP address information of the server to connect to */ 
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr=inet_addr(argv[1]);
        servaddr.sin_port=htons(32000);
    
        connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    
        /*Ask user to specify required file name*/
        printf("What's the required file ? ");
        scanf("%s",buffer);
    
        /*Send requested file name to server*/
        sendto(sockfd,buffer,SIZE,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
        n=recvfrom(sockfd,buffer,SIZE,0,NULL,NULL);
        buffer[n]=0;
    
        /*If server found that file is not present it sends a NACK*/
        if(!strcmp(buffer,"NACK")){
            printf("Required file not in server..\n");
            return(1);
        }
    
        /*Else server send the size of the file*/
        printf("FIle size is %s bytes \n",buffer);
        len=atoi(buffer);
    
        /* Open/create file to save recieved data*/
        ff=fopen("clientfile.txt","w"); /*OPen or create the file to be written*/
    
        /*Check for file creation success*/
        if(ff==NULL){
            strcpy(buffer,"NACK");
            sendto(sockfd,buffer,SIZE,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
            printf("File creating failled.. \n");
            return(0);
        }
    
    
        /*Client stays in a loop till it recieve full data*/
        int c=0;
        while(c<len){
    
            /*Each time client sends ACK to recieve next data chunk*/
            strcpy(buffer,"ACK");
            sendto(sockfd,buffer,SIZE,0, (struct sockaddr *)&servaddr,sizeof(servaddr));
    
            n=recvfrom(sockfd,buffer,sizeof(buffer),0,NULL,NULL);
            printf("Recieved %d bytes\n",n);
    
            /*Increase counter by recieve chunk size*/
            c+=n;
    
            /*Add null character to end of data*/
            if(c>=len){
                buffer[n]='\0';
            }
    
            /*Append to file*/
            fwrite(buffer,sizeof(char),n,ff);
        }
    
        fclose(ff);
        printf("File sucessfully recieved..\n");
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-03-21
      • 1970-01-01
      • 2011-04-06
      • 2013-07-09
      • 1970-01-01
      • 2015-02-28
      • 1970-01-01
      • 2021-08-20
      • 2020-09-05
      相关资源
      最近更新 更多