程序应该将文件的内容从客户端发送到服务器端的输出文件。但是,我的代码适用于少数文件而不适用于大多数文件。例如,如果我尝试将名为morefood.txt
的文件的内容复制到输出文件picolo.txt
,则不会复制任何内容。
服务器代码:
#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);
FILE* fp = fopen( "picolo.txt", "wb");
if(fp == NULL){
fprintf(stderr, "something went south");
return 1;
}
while(1){
confd = accept(fd, (struct sockaddr*)NULL, NULL);
char recvbuff[10];
int b = recv(confd, recvbuff, 10, 0);
while(b>0)
{
fwrite(recvbuff, 1, b, fp);
b = recv(confd, recvbuff, 10, 0);
}
close(confd);
}
return 0;
}
客户代码:
#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 sfd =0, n=0;
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("127.0.0.1");
connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
FILE *fp = fopen("morefood.txt", "rb");
if(fp == NULL){
fprintf(stderr, "oh no!");
return 1;
}
char sendbuffer[100];
int b = fread(sendbuffer, 1, sizeof(sendbuffer), fp);
while(!feof(fp)){
send(sfd, sendbuffer, b, 0);
b = fread(sendbuffer, sizeof(sendbuffer), 1, fp);
}
return 0;
}
答案 0 :(得分:2)
此代码,在客户端:
char sendbuffer[100];
int b = fread(sendbuffer, 1, sizeof(sendbuffer), fp);
while(!feof(fp)){
send(sfd, sendbuffer, b, 0);
b = fread(sendbuffer, sizeof(sendbuffer), 1, fp);
}
不是一个发送无名&#39;的好方法。文件。
我建议
while( 0< (byteCount = fread( sendbuffer, sizeof(sendbuffer), 1, fp) ) )
{
send(sfd, sendbuffer, byteCount, 0);
}
然而,为了稳健性
--client send a file name and total file size with recordNum 0
--server when receiving recordNum 0
open the appropriate file name
if successful open, send 'ack', maxRecordSize echo recordNum
else send 'nak' echo recordNum
--client, on following records,
send byteCount, recordNum, data
--server respond with 'ack' for each received record
when it is expected recordNum
otherwise respond with 'nak' expected recordNum
--when client receives 'ack' send next record
--when client receives 'nak' resend prior record
--client, after all file sent, send file checksum with recordnum -1
--server, when receive recordNum -1 compares checksum, closes file
responds with final 'ack' if checksum matches
responds with final 'nak' if checksum does not match
这个&#39;锁步&#39;通信,通常在现实世界中使用, 将确保通信的两端知道发生了什么 并确保成功的文件传输,
这适用于一次只发送一个文件。 对于同时发送的多个文件, 记录将需要另一个字段,指示哪个文件 &#39;这&#39;记录是其中的一部分。
当然,所有send / recv / open / connect / bind / etc系统函数调用都需要检查返回值是否有错误
答案 1 :(得分:1)
问题是传输和接收循环都被窃听!我已经以一种代码运行得更好的方式对它们进行了修改,但我认为要修改它以获得可靠的代码!
客户端:
#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 sfd =0, n=0, b;
char rbuff[1024];
char sendbuffer[100];
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("127.0.0.1");
b=connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (b==-1) {
perror("Connect");
return 1;
}
FILE *fp = fopen("prova.jpg", "rb");
if(fp == NULL){
perror("File");
return 2;
}
while( (b = fread(sendbuffer, 1, sizeof(sendbuffer), fp))>0 ){
send(sfd, sendbuffer, b, 0);
}
fclose(fp);
return 0;
}
服务器:
#include <stdio.h>
#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,b,tot;
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);
if (confd==-1) {
perror("Accept");
continue;
}
FILE* fp = fopen( "provacopy.jpg", "wb");
tot=0;
if(fp != NULL){
while( (b = recv(confd, buff, 1024,0))> 0 ) {
tot+=b;
fwrite(buff, 1, b, fp);
}
printf("Received byte: %d\n",tot);
if (b<0)
perror("Receiving");
fclose(fp);
} else {
perror("File");
}
close(confd);
}
return 0;
}
答案 2 :(得分:0)
要从服务器中的文件读取的部分
.
. // Your other code
.
read(client, rbuff, sizeof(rbuff); //Getting file name from client
printf("File wanted by client%s\n", textToRec);
int filedesc = open(textToRec, O_RDONLY); //Opening the file
struct stat sb; //To get the size of file
if (lstat(ruff, &sb) == -1) {
exit(EXIT_FAILURE);
}
long long fsize;
fsize = sb.st_size;
if ((0 == filedesc)) {
fprintf(stderr,"error in reading file");
exit(-1);
}
write(client, fsize, sizeof(fsize)); //Sending Filesize
read(filedesc, sendbuffer, fsize); //Putting file in buffer
write(client, sendbuffer, sizeof(sendbuffer)); //Sending buffer to client
close(socketid);
.
.
. // Your code
客户端部分:
/* your code above */
printf("file name sent...Now wait!\n");
// I am assuming you put filename in buff
read(sock, buff,sizeof(buff)); //Receiving file size
long long fsize = strtol(buff,NULL,10);
read(sock, buff,sizeof(buff));
/*It's better to use sizeof instead of actual number as you can change the size of buffer anytime without needing to change values everywhere */
int filedesc;
filedesc =
open(textToSend, O_WRONLY | O_APPEND | O_CREAT, 0644);
if (!filedesc) {
printf("failed to create file\n");
exit;
}
write(filedesc, buff, fsize);
close(filedesc);
close(confd);