我必须使用UDP进行服务器 - 客户端文件传输。我创建了一个基本服务器,它接收客户端发送的消息。就这样。 现在主要是: -
1. The message sent by client is the name of file .
2. Now the server checks whether there exists this file or not .
3. If there exists it sends the file to the client and it also keeps the count of the number of requests of file made by the client .
我是新手,我不知道如何继续前进。
这是服务器代码
#include<sys/socket.h>
#include<arpa/inet.h>
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<string.h>
int main()
{
char buff[2000];
char file_buffer[2000];
int sd,connfd,len;
struct sockaddr_in servaddr,cliaddr;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if(sd==-1)
{
printf(" socket not created in server\n");
exit(0);
}
else
{
printf("socket created in server\n");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(7802);
if ( bind(sd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0 )
printf("Not binded\n");
else
printf("Binded\n");
len=sizeof(cliaddr);
recvfrom(sd,buff,1024,0,
(struct sockaddr *)&cliaddr, &len);
printf("%s\n",buff);
/* */
FILE *fp;
fp=fopen(buff,"r");
if(fp==NULL)
{
printf("file does not exist\n");
}
fseek(fp,0,SEEK_END);
size_t file_size=ftell(fp);
fseek(fp,0,SEEK_SET);
if(fread(file_buffer,file_size,1,fp)<=0)
{
printf("unable to copy file into buffer\n");
exit(1);
}
if(sendto(sd,file_buffer,strlen(file_buffer),0, (struct sockaddr *)&cliaddr, &len)<0) {
printf("error in sending the file\n");
exit(1);
}
bzero(file_buffer,sizeof(file_buffer));
/* */
close(sd);
return(0);
}
这是客户端代码
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include<netinet/in.h>
#include<sys/types.h>
int main()
{
char buff[2000];
int sockfd,connfd,len;
struct sockaddr_in servaddr,cliaddr;
// create socket in client side
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sockfd==-1)
{
printf(" socket not created in client\n");
exit(0);
}
else
{
printf("socket created in client\n");
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY; // ANY address or use specific address
servaddr.sin_port = htons(7802); // Port address
printf("Type ur UDP client message\n");
scanf("%s",buff);
// send msg to server
sendto(sockfd, buff, strlen(buff), 0,
(struct sockaddr *)&servaddr, sizeof(struct sockaddr));
char file_buffer[2000];
if (recvfrom(sockfd,file_buffer,2000,0, (struct sockaddr *)&servaddr, sizeof(struct sockaddr))<0)
{
printf("error in recieving the file\n");
exit(1);
}
char new_file[]="copied";
strcat(new_file,buff);
FILE *fp;
fp=fopen(new_file,"w+");
if(fwrite(file_buffer,1,sizeof(file_buffer),fp)<0)
{
printf("error writting file\n");
exit(1);
}
//close client side connection
close(sockfd);
return(0);
}
我编辑了程序并创建了一个新的缓冲区file_buffer,服务器从文件中读取数据并写入其中并发送到客户端,另一端客户端接收数据并复制此文件并写入其中。但在编译时,它会在写入文件时出错:(
答案 0 :(得分:1)
您必须在两个地方扩展逻辑。基本上对于服务器代码,您可以使用buff作为文件名并检查它是否存在。您可以使用“fopen(buff,”r“)” - 如果这返回NULL,则该文件不存在,在这种情况下,您可能希望向客户端发送一条说明该文件不存在的注释。像这样:
FILE *istream;
strncpy(fileName, buff, ret_len + 1);
if ( (istream = fopen(fileName, "r" ) ) == NULL ){
printf ( "file non-existant!\n" );
strncpy(buff, "Does not Exist", strlen("Does Not Exist"));
} else {
printf ( "file exists!\n" );
strncpy(buff, "Does Exist", strlen("Does Exist"));
fclose (istream );
}
ret_len = sendto(sd, buff, strlen(buff), 0, (struct sockaddr *)&cliaddr, sizeof(struct sockaddr));
if (ret_len < 0) {
fprintf(stderr, "sendto() failed [ret value: %d]\n", ret_len);
return -1;
}
如果文件存在,则读取文件并将内容发送到文件。
客户端在将缓冲区发送到服务器后必须从服务器执行recvfrom()!像这样的东西。请注意,您可以使用数值(-1或0)来指示文件是否存在。如果文件存在,您可以在初始消息中传递文件长度 - 这样,客户端就会知道需要读取多少数据。
// send msg to server
sendto(sockfd, buff, strlen(buff) + 1, 0, (struct sockaddr *)&servaddr, sizeof(struct sockaddr));
// recveive from server
ret_len = recvfrom(sockfd, buff, 1024, 0, NULL, 0);
printf("Received from server: %s \n",buff);
if (strncmp(buff, "Does not Exist", strlen("Does not Exist")) == 0)
printf("File does not exist\n");
else if (strncmp(buff, "Does Exist", strlen("Does Exist")) == 0)
printf("File does exist\n");
else
printf("Unknown message\n");
顺便说一句,在上面的代码中,我们需要为NUL字符添加1。此外,完成此步骤后,客户端代码应在循环中调用recvfrom()以从服务器接收数据,如前面步骤中所述。
请注意,如果文件太大,那么您可能只想读取它想要发送的消息 - 使用UDP可以发送高达64K但理想情况下最多只能发送1 MUT(大约1500)字节)。
答案 1 :(得分:1)
我不确定您是否必须开发自己的客户端/服务器,或者您是否可以使用其他客户端/服务器?还有一些其他基于开源UDP的文件传输系统,如UDT,UFTP,Tsunami-UDP,甚至谷歌的QUIC。
答案 2 :(得分:0)
您是否希望服务器的行为类似于FTP服务器?
从客户端收到文件名后,检查是否存在。见What's the best way to check if a file exists in C? (cross platform)。然后打开文件并通过缓冲区(例如,每次200字节)将缓冲区发送给客户端。同时,客户端接收它并写入名为 filename 的新文件。