所以在这个程序中我试图通过两个步骤将文件内容和文件名从客户端发送到服务器。我尝试使用memset()
清空缓冲区以便用它来存储文件名,然后我意识到文件名与内容一起传递到缓冲区,所以没有{{1}的意思}。所以,我需要将两个传输分开,我正在考虑关闭第一个进程的缓冲区,然后再次打开它进行第二次传输,我不知道如何继续。
这是我的代码:
Server.c
memset()
Client.c
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
int main(int argc, char *argv[]){
int fd =0, confd = 0;
struct sockaddr_in serv_addr;
char buff[1025];
int num;
fd = socket(AF_INET, SOCK_STREAM, 0);
printf("Socket created\n");
memset(&serv_addr, '0', sizeof(serv_addr));
memset(buff, '0', sizeof(buff));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(fd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(fd, 10);
while(1){
confd = accept(fd, (struct sockaddr*)NULL, NULL);
FILE* fp = fopen( "create.txt", "wb");
int b = recv(confd, buff, 1024, 0);
if(fp!=NULL){
while(b>0){
fwrite(buff, 1, b, fp);
b = recv(confd, buff, 1024, 0);
}
}
else{
printf("Error!");
}
printf("Got it :)\n");
//printf("Buff before: %s\n", buff);
memset(buff, 0, sizeof(buff));
num = read(confd, buff, 1024);
//printf("Buff after: %s\n", buff);
if(num<0){
printf("error reading the socket");}
else{
printf("File uploaded: %s\n", buff);
}
//close(confd);
fclose(fp);
}
return 0;
}
有人可以帮忙吗?
EDIT1:
在发送文件内容之前发送文件名似乎有效,但是这样做会打印很长的零跟踪。例如:#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
int main(int argc, char *argv[]){
int i=0, k=0,num;
char ip[50];
char upfile[50];
char dwfile[50];
for(i=0; i<argc; i++){
if(strcmp(argv[i], "-i")==0){
strcpy(ip, argv[i+1]);
}
else if(strcmp(argv[i],"-u")==0){
strcpy(upfile, argv[i+1]);
k =2;
}
else if(strcmp(argv[i], "-d")==0){
strcpy( dwfile, argv[i+1]);
k=3; }
/* else(argv[i] = "-l"){
}*/
}
printf("%s %s %s", ip, upfile, dwfile);
int sfd =0, n=0, c;
char rbuff[1024];
struct sockaddr_in serv_addr;
memset(rbuff, '0', sizeof(rbuff));
sfd = socket(AF_INET, SOCK_STREAM, 0);
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
serv_addr.sin_addr.s_addr = inet_addr(ip);
c = connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if(c==-1){
perror("Connect");
return 1;
}
if (k==2){
printf("==========This is the upload function");
FILE *fp = fopen(upfile, "rb");
if(fp == NULL){
fprintf(stderr, "oh no!");
return 1;
}
char sendbuffer[100];
int b = fread(sendbuffer, 1, sizeof(sendbuffer),fp);
while(b>0){
send(sfd, sendbuffer, b, 0);
b = fread(sendbuffer, 1, sizeof(sendbuffer),fp);
}
num = write(sfd, upfile, strlen(upfile));
fclose(fp);
printf("Send filename: %s", upfile);
printf("============End upload!");
}
return 0;
}
答案 0 :(得分:3)
有两种常见的解决方案:一种是使用分隔符,特殊字节或字节序列,它们不能存储在消息数据中,而是标记两条消息之间的分隔符。在你发送二进制文件的情况下,它实际上并不可行,因为实际上没有安全序列。
另一种常见的方法是使用一个特殊的固定大小的标题,其中包含您发送的数据的长度。然后,您只需先发送此固定大小的标题,然后再输入实际数据。
在你的情况下你可以实际使用这两种方法,但我真的建议你先发送文件名 ,否则服务器很难打开文件并写入数据。
你可以发送带有终止零的文件名,从而将字符串终止符作为文件名和文件数据之间的字段分隔符。
或您可以发送文件名和文件数据的长度,后跟名称和数据。
答案 1 :(得分:0)