如何使用recv逐行阅读html页面?

时间:2015-02-19 10:07:50

标签: c sockets recv

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

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

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

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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

您的要求没有standard实施。您需要做的是拥有一个正确的sending和一个receiving套接字程序。

建议方法:

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

您需要什么:

此外:以下是我的示例代码

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

服务器:

#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;
}