如何使用 recv 逐行阅读 html 页?
How can i read html page line by line using recv?
我尝试用C语言练习socket编程
我试图做的是逐行阅读某些 html 页,这意味着一直读到 '\n'。
但是,问题是由于 recv 的属性读取一定长度,我们将其作为参数传递给 recv() 的第三个参数。
例如,
char buff[256];
.
.
recv(socknumber, buf, sizeof(buff), 0);
在这种情况下,recv 读取的字符串与 sizeof(buff) 一样多。所以我不知道如何处理 '\n'
由于我是C处女,请给我一些提示,或者简单的代码。谢谢
socket传输没有线路的概念,需要自己实现。即使在 SO 中也有很多解决方案,请参阅那个 read line by line from a socket buffer。您还可以从套接字描述符中获取 FILE
句柄并使用 *gets
函数(如果您使用的是 Unix,请查看 fdopen
)。
没有 standard
实现您的要求。你需要做的是有一个合适的 sending
和一个 receiving
套接字程序。
一个建议方法:
Sender
逐块读取 HTML 文件(假设每次读取 100 个字节)并将它们发送到 reciever
Receiver
接受发送方发送的数据块并写入文件。
(接收方知道块的大小)
- 您可以在开始传输前指定文件长度。
您需要什么:
此外:这是我的示例代码集
"Client
按名称请求文件和 server
响应文件(如果可用)逐块请求"=22=]
服务器:
#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] = '[=10=]';
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]='[=11=]';
}
/*Append to file*/
fwrite(buffer,sizeof(char),n,ff);
}
fclose(ff);
printf("File sucessfully recieved..\n");
return 0;
}
我尝试用C语言练习socket编程
我试图做的是逐行阅读某些 html 页,这意味着一直读到 '\n'。
但是,问题是由于 recv 的属性读取一定长度,我们将其作为参数传递给 recv() 的第三个参数。
例如,
char buff[256];
.
.
recv(socknumber, buf, sizeof(buff), 0);
在这种情况下,recv 读取的字符串与 sizeof(buff) 一样多。所以我不知道如何处理 '\n'
由于我是C处女,请给我一些提示,或者简单的代码。谢谢
socket传输没有线路的概念,需要自己实现。即使在 SO 中也有很多解决方案,请参阅那个 read line by line from a socket buffer。您还可以从套接字描述符中获取 FILE
句柄并使用 *gets
函数(如果您使用的是 Unix,请查看 fdopen
)。
没有 standard
实现您的要求。你需要做的是有一个合适的 sending
和一个 receiving
套接字程序。
一个建议方法:
Sender
逐块读取 HTML 文件(假设每次读取 100 个字节)并将它们发送到reciever
Receiver
接受发送方发送的数据块并写入文件。 (接收方知道块的大小)- 您可以在开始传输前指定文件长度。
您需要什么:
此外:这是我的示例代码集
"Client
按名称请求文件和 server
响应文件(如果可用)逐块请求"=22=]
服务器:
#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] = '[=10=]';
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]='[=11=]';
}
/*Append to file*/
fwrite(buffer,sizeof(char),n,ff);
}
fclose(ff);
printf("File sucessfully recieved..\n");
return 0;
}