Внештатное исполнение для вашего требования 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;
}
На современных системах POSIX' recv' эквивалентно 'read', если не проходит ни флаги, и вы можете попробовать использовать 'fdopen' для разбора сокета как обычного stdio' FILE', например с 'fgets' или whatnot для извлечения строк. К сожалению, это не будет работать с Winsock в системах Windows. – doynax
"html-страница по строкам". HTML-страницы не состоят из строк. –