我尝试使用C语言练习套接字编程
我尝试做的是逐行读取某些html页面,这意味着阅读直到' \ n'。
但问题是,由于recv的读取一定长度的属性,我们将其作为参数传递给recv()的第三个参数。
例如,
char buff[256];
.
.
recv(socknumber, buf, sizeof(buff), 0);
在这种情况下,recv读取字符串和sizeof(buff)一样多。所以我不知道如何处理' \ n'
由于我是C处女,请给我一些提示或简单的代码。感谢。
答案 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;
}